java 字符串zlib压缩/解压

时间:2023-03-09 16:55:27
java 字符串zlib压缩/解压

今天在测公司的中间件时发现,增加netty自带的zlib codec压缩处理后,就报decompress failed, invalid head之类的异常。后来发现,直接用bytebuf处理报文体是正常的,但是增加了stringencoder/decoder之后,就会出现这个异常。本来之前就想把这一步逻辑优化成报文体尽可能delay解压的,于是干脆给调整了。

因为java中,string\byte尤其是各种加密、加密操作增加的各种辅助信息,使得他们俩不能跟大部分普通操作的字符串转换一样互转,需要适用base64特殊处理后才能互转,如下:

public class ZlibUtils {

    public static String compress(String data) {
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
ZOutputStream zOut = new ZOutputStream(out,
JZlib.Z_BEST_COMPRESSION);
ObjectOutputStream objOut = new ObjectOutputStream(zOut);
objOut.writeObject(data);
zOut.close();
return Base64.encodeBase64String(out.toByteArray());
} catch (IOException e) {
e.printStackTrace();
}
return null;
} public static String decompress(String data) {
try {
ByteArrayInputStream in = new ByteArrayInputStream(
Base64.decodeBase64(data));
ZInputStream zIn = new ZInputStream(in);
ObjectInputStream objIn = new ObjectInputStream(zIn);
return (String) objIn.readObject();
} catch (Exception e) {
e.printStackTrace();
}
return null;
} public static void main(String[] args) throws UnsupportedEncodingException {
String compressed = compress("0000007901qqqq.qq.qqqqqqqq0000002171779ad0dfdb4a4f9ac4be18ef3a78080837403181000drpcpqq");
System.out.println(compressed.length());
System.out.println(decompress(compressed));
System.out.println(System.currentTimeMillis());
compressed = compress("兼容性要求(参考OS/浏览器市场份额调查报告http://www.jiangweishan.com/article/marketData.htmlhttp://www.jiangweishan.com/article/marketData.htmlhttp://www.jiangweishan.com/article/marketData.html|http://www.jiangweishan.com/article/marketData2016.html):兼容性要求(参考OS/浏览器市场份额调查报告http://www.jiangweishan.com/article/marketData.html|http://www.jiangweishan.com/article/marketData2016.html):");
System.out.println(decompress(compressed));
}
}

这样就可以完全做到string进string出了,不过因为base64会增加大约1/3的额外大小,抵消了部分压缩的效果。

Base64编码说明
  Base64编码要求把3个8位字节(3*8=24)转化为4个6位的字节(4*6=24),之后在6位的前面补两个0,形成8位一个字节的形式。 如果剩下的字符不足3个字节,则用0填充,输出字符使用'=',因此编码后输出的文本末尾可能会出现1或2个'='。

  为了保证所输出的编码位可读字符,Base64制定了一个编码表,以便进行统一转换。编码表的大小为2^6=64,这也是Base64名称的由来。