资讯专栏INFORMATION COLUMN

记一次字符串压缩操作

王笑朝 / 1019人阅读

摘要:记一次字符串压缩操作项目中遇到一个场景需要将一批数据发送到端,且实际应用场景中,对数据的长度有一定的限制,于是就需要用到字符串压缩。端使用,后端使用,使用压缩,同时涉及到了编码,中文和西欧字符集转码。

记一次字符串压缩操作

项目中遇到一个场景:需要将一批数据发送到APP端,且实际应用场景中,对数据的长度有一定的限制,于是就需要用到字符串压缩。
APP端使用Java,后端使用Golang,使用gzip压缩,同时涉及到了base64编码,中文和西欧字符集转码。

过程描述

后端:

字符集转换 参考自:一个复杂的中文编码问题

压缩字符串

使用base64编码为可见字符

网络传输

APP端

接收网络响应

base64解码,得到一个字节数组(压缩的)

gzip读取压缩的字节流,解压缩

转码为中文

示例代码

所有示例代码可以在这里找到

server端

func compress(s string) string {
    //使用GBK字符集encode
    gbk, err := simplifiedchinese.GBK.NewEncoder().Bytes([]byte(s))
    if err != nil {
        logrus.Error(err)
        return ""
    }

    //转为ISO8859_1,也就是latin1字符集
    latin1, err := charmap.ISO8859_1.NewDecoder().Bytes(gbk)
    if err != nil {
        return ""
    }

    //使用gzip压缩
    var buf bytes.Buffer
    zw := gzip.NewWriter(&buf)

    _, err = zw.Write(latin1)
    if err != nil {
        logrus.Fatal(err)
    }

    if err := zw.Close(); err != nil {
        logrus.Fatal(err)
    }

    //使用base64编码
    encoded := base64.StdEncoding.EncodeToString(buf.Bytes())
    fmt.Println(encoded)
    return encoded
}

APP端

private static String uncompress(String s) throws IOException {

        //base64 decode
        byte[] byteArray = Base64.getDecoder().decode(s);
        ByteArrayInputStream bis = new ByteArrayInputStream(byteArray);
        
        //gzip解压
        GZIPInputStream gis = new GZIPInputStream(bis);
        BufferedReader br = new BufferedReader(new InputStreamReader(gis, "UTF-8"));
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        br.close();
        gis.close();
        bis.close();

        //使用latin1字符集获得bytes
        byte[] latin1 = sb.toString().getBytes("ISO_8859_1");
        //转换回GBK
        return new String(latin1, "GBK");
    }

使用base64编码,主要是因为经过gzip压缩后数据,直接转成字符串的话,会有很多不可见字符,这样在传输过程中,通常会被服务端框架转义,从而失真。
代码仅作为示例使用,实际业务编码请注意检查错误和异常等。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/72439.html

相关文章

  • 一次Content-Length引发的血案

    摘要:除非使用了分块编码,否则首部就是带有实体主体的报文必须使用的。 背景 新项目上线, 发现一个奇怪的BUG, 请求接口有很小的概率返回400 Bad Request,拿到日志记录的请求的参数于POSTMAN中测试请求接口, 发现能够正常响应. 排查过程 首先服务器能够正常响应400 Bad Request, 排除接口故障问题. 对比日志过程中发现 { hello:world ...

    thekingisalwaysluc 评论0 收藏0
  • 一次webpack打包

    摘要:记一次打包前言公司的一个公众号要做一个的活动很简单的两个页面写完之后我想要不要去做一下压缩还是直接放上去就好了后面一想还是做下压缩吧正好重新学习下以前用都是人家写好的手脚架拿来直接用的自己改改没啥问题但是要自己重新搭一套好像也不太会所以趁这 记一次webpack打包 前言 公司的一个公众号要做一个H5的活动. 很简单的两个页面, 写完之后, 我想要不要去做一下压缩, 还是直接放上去...

    Profeel 评论0 收藏0
  • 一次上古项目的限时开发

    摘要:钉钉新需求沟通后了解到,是一个临时需求。开始部署环境一个项目开发的前提是什么是正常运行并开启调试模式。及时复盘项目的开发流程,记录开发计划中遇到的协作问题和技术问题。 ➢ 钉钉新需求 沟通后了解到,是一个临时需求。 在一个老项目上。 具体有多老,直到开发完也不知道。 showImg(https://segmentfault.com/img/remote/1460000019364396...

    mykurisu 评论0 收藏0
  • 一次上古项目的限时开发

    摘要:钉钉新需求沟通后了解到,是一个临时需求。开始部署环境一个项目开发的前提是什么是正常运行并开启调试模式。及时复盘项目的开发流程,记录开发计划中遇到的协作问题和技术问题。 ➢ 钉钉新需求 沟通后了解到,是一个临时需求。 在一个老项目上。 具体有多老,直到开发完也不知道。 showImg(https://segmentfault.com/img/remote/1460000019364396...

    crossea 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<