java实现deflate数据压缩和gzip数据压缩


一、概念区别

gzip是一种数据格式,默认且目前仅使用deflate算法压缩data部分;
deflate是一种压缩算法,是huffman编码的一种加强。

deflate与gzip解压的代码几乎相同,可以合成一块代码。

区别仅有:
deflate使用inflateInit(),而gzip使用inflateInit2()进行初始化,比 inflateInit()多一个参数: -MAX_WBITS,
表示处理raw deflate数据。因为gzip数据中的zlib压缩数据块没有zlib header的两个字节。使用inflateInit2时要求zlib库忽略zlib header。
在zlib手册中要求windowBits为8..15,但是实际上其它范围的数据有特殊作用,见zlib.h中的注释,如负数表示raw deflate。
Apache的deflate变种可能也没有zlib header,需要添加假头后处理。即MS的错误deflate (raw deflate).zlib头第1字节一般是0x78, 
第2字节与第一字节合起来的双字节应能被31整除,详见rfc1950。
例如Firefox的zlib假头为0x7801,python zlib.compress()结果头部为0x789c。

deflate 是最基础的算法,gzip 在 deflate 的 raw data 前增加了 10 个字节的 gzheader,
尾部添加了 8 个字节的校验字节(可选 crc32 和 adler32) 和长度标识字节。

一、代码封装

import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.zip.Deflater;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import java.util.zip.Inflater;

/**
 * @Title: CompressUtil
 * @Description:
 * @Author cw
 * @DateTime: 2022/12/30 10:45
 */
public class CompressUtil {

    /**
     * 文本数据gzip压缩
     */
    public static String gzipCompressString(String text) {
        if (StringUtils.isEmpty(text)) {
            return null;
        }

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream)) {
            gzipOutputStream.write(text.getBytes(StandardCharsets.UTF_8));
            gzipOutputStream.flush();
            gzipOutputStream.finish();
        } catch (Exception e) {
            System.out.println(e);
            return null;
        }

        return Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());
    }
    /**
     * 文本数据gzip解压
     */
    public static String gzipDecompressString(String text) {
        if (StringUtils.isEmpty(text)) {
            return null;
        }

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(Base64.getDecoder().decode(text));
        try (GZIPInputStream gzipInputStream = new GZIPInputStream(byteArrayInputStream)){
            byte[] buffer = new byte[256];
            int len;
            while ((len = gzipInputStream.read(buffer)) != -1) {
                byteArrayOutputStream.write(buffer, 0, len);
            }
        }catch (Exception e){
            System.out.println(e);
            return null;
        }

        return byteArrayOutputStream.toString();
    }
    /**
     * 字节数组gzip压缩
     */
    public static byte[] gzipCompressBytes(byte[] bytes) {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream)) {
            gzipOutputStream.write(bytes);
            gzipOutputStream.flush();
            gzipOutputStream.finish();
        } catch (Exception e) {
            System.out.println(e);
            return null;
        }

        return byteArrayOutputStream.toByteArray();
    }

    /**
     * @param bytes 待解压缩的字节数组
     * @return 解压缩后的字节数组
     * @throws IOException
     */
    public static byte[] deflateDecompressBytes(byte[] bytes) throws IOException {
        int len = 0;
        Inflater infl = new Inflater();
        infl.setInput(bytes);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte[] outByte = new byte[1024];
        try {
            while (!infl.finished()) {
                len = infl.inflate(outByte);
                if (len == 0) {
                    break;
                }
                bos.write(outByte, 0, len);
            }
            infl.end();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            bos.close();
        }
        return bos.toByteArray();
    }

    /**
     * 压缩.
     *
     * @param bytes 待压缩的字节数组
     * @return 压缩后的数据
     * @throws IOException
     */
    public static byte[] deflateCompressBytes(byte[] bytes) throws IOException {
        int len = 0;
        Deflater defl = new Deflater();
        defl.setInput(bytes);
        defl.finish();
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte[] outputByte = new byte[1024];
        try {
            while (!defl.finished()) {
                len = defl.deflate(outputByte);
                bos.write(outputByte, 0, len);
            }
            defl.end();
        } finally {
            bos.close();
        }
        return bos.toByteArray();
    }
}

参考文章:
https://www.php1.cn/detail/JAVA_ZhongDe_def_7c4ff3e8.html
https://blog.csdn.net/gehong3641/article/details/127079600
https://blog.csdn.net/iteye_6926/article/details/82649870

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值