java 字符串zlib压缩/解压

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

因为java中,stringyte尤其是各种加密、加密操作增加的各种辅助信息,使得他们俩不能跟大部分普通操作的字符串转换一样互转,需要适用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名称的由来。

原文地址:https://www.cnblogs.com/zhjh256/p/6071359.html