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
    评论
Java文件压缩与解压缩实践是指利用Java编程语言实现对文件或文件夹进行压缩和解压缩操作。以下是该实践的描述: 技术概述: Java文件压缩与解压缩是指将一个或多个文件或文件夹打包成一个压缩文件,或者将压缩文件解压缩成原始文件的过程。 常见的压缩格式包括ZIP、GZIP、TAR等,Java提供了相应的API来实现对这些格式的操作。 功能特点: 文件压缩:将一个或多个文件或文件夹压缩成一个压缩文件,减小文件大小,便于存储和传输。 文件解压缩:将压缩文件解压缩成原始文件,恢复文件的原始内容和结构。 支持多种压缩格式:Java提供了对多种常见压缩格式的支持,如ZIP、GZIP等。 异常处理:处理压缩和解压缩过程中可能出现的异常,保证程序的稳定性和可靠性。 技术实现: 压缩API:Java提供了java.util.zip和java.util.jar包来实现文件的压缩和解压缩操作。 压缩算法:通过选择不同的压缩算法,如DEFLATE算法用于ZIP格式,实现对文件的压缩。 流操作:使用Java的输入输出流(InputStream、OutputStream)来读取和写入文件内容。 异常处理:通过捕获并处理IOException等异常,确保程序在压缩和解压缩过程中的稳定性。 应用领域: Java文件压缩与解压缩实践广泛应用于文件备份、数据传输、打包软件、日志管理等各个领域。 在网络传输中,可以将多个文件打包成一个压缩文件进行传输,减少传输时间和网络带宽的消耗。 在软件开发中,可以将项目源代码、资源文件等打包成压缩文件进行发布和分享。 通过Java文件压缩与解压缩实践,可以方便地对文件进行打包和解包操作,提高文件的管理和传输效率。
Java后端和浏览器中使用Pako.js实现Gzip的压缩和解压方法是不同的。 浏览器端: 压缩: ``` var buffer = new Uint8Array(inputString.length); for (var i = 0; i < inputString.length; i++) { buffer[i] = inputString.charCodeAt(i); } var compressed = pako.gzip(buffer); var outputString = String.fromCharCode.apply(null, new Uint16Array(compressed)); ``` 解压: ``` var compressed = new Uint8Array(inputString.length); for (var i = 0; i < inputString.length; i++) { compressed[i] = inputString.charCodeAt(i); } var decompressed = pako.inflate(compressed); var outputString = String.fromCharCode.apply(null, new Uint16Array(decompressed)); ``` 与在浏览器端相同,我们首先将输入字符串转换为一个Uint8Array,然后使用Pako.js的gzip函数将其压缩。最后,我们将压缩后的结果转换回字符串形式。 在解压的过程中,我们将输入字符串转换为Uint8Array,然后使用Pako.js的inflate函数将其解压,最后将结果转换回字符串形式。 需要注意的是,最后转换为字符串时要使用Uint16Array而不是Uint8Array,这是因为JavaScript中的字符串是基于UTF-16编码的。 Java后端: Java后端可以使用Java版的Pako库实现Gzip的压缩和解压。 引入Java版的Pako库: ``` <dependency> <groupId>io.github.azagniotov</groupId> <artifactId>pako-java</artifactId> <version>1.0.1</version> </dependency> ``` 压缩: ``` String inputString = "input string"; byte[] inputBytes = inputString.getBytes(StandardCharsets.UTF_8); byte[] compressedBytes = new Deflater().deflate(inputBytes); String outputString = new String(compressedBytes, StandardCharsets.ISO_8859_1); ``` 解压: ``` byte[] compressedBytes = inputString.getBytes(StandardCharsets.ISO_8859_1); Inflater inflater = new Inflater(); inflater.setInput(compressedBytes); byte[] buffer = new byte[1024]; ByteArrayOutputStream outputStream = new ByteArrayOutputStream(compressedBytes.length); while (!inflater.finished()) { int count = inflater.inflate(buffer); outputStream.write(buffer, 0, count); } outputStream.close(); byte[] decompressedBytes = outputStream.toByteArray(); String outputString = new String(decompressedBytes, StandardCharsets.UTF_8); ``` 在Java中,我们使用Deflater类的deflate方法进行压缩,使用Inflater类进行解压。需要注意的是,在解压的过程中,我们需要使用一个字节输出流ByteArrayOutputStream来存储解压后的字节,最后再将其转换为字符串形式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值