GZIP工具-Gzip
# 📚简介
Gzip类是Hutool压缩模块中用于处理GZIP压缩和解压缩的工具类,它对JDK的java.util.zip.GZIPInputStream和GZIPOutputStream进行了封装,提供了更简洁易用的API,简化了GZIP压缩和解压缩操作。
GZIP是Unix系统中常用的文件压缩格式,其基础是DEFLATE压缩算法。与ZIP格式不同,GZIP通常用于压缩单个文件,而不是多个文件的归档。
# 🏗️核心结构
# 1. 类定义
public class Gzip implements Closeable {
private InputStream source;
private OutputStream target;
// ...
}
# 2. 核心属性
| 属性名 | 类型 | 描述 |
|---|---|---|
source | InputStream | 源流,用于读取原始数据或压缩数据 |
target | OutputStream | 目标流,用于写入压缩数据或解压缩后的数据 |
# 🔧 API说明
# 1. 创建Gzip实例
# of(InputStream source, OutputStream target)
创建Gzip实例,用于后续的压缩或解压缩操作。
参数说明:
source:源流,可以是普通输入流或GZIP输入流target:目标流,可以是普通输出流或GZIP输出流
返回值:
- Gzip实例,用于链式调用
# 2. 压缩操作
# gzip()
将普通数据流压缩为GZIP格式。
返回值:
- Gzip实例,用于链式调用
实现逻辑:
- 如果目标流不是GZIPOutputStream,则创建一个新的GZIPOutputStream
- 将源流的数据复制到目标流
- 调用finish()方法完成压缩
- 抛出IORuntimeException处理IO异常
# 3. 解压缩操作
# unGzip()
将GZIP压缩流解压缩为普通数据流。
返回值:
- Gzip实例,用于链式调用
实现逻辑:
- 如果源流不是GZIPInputStream,则创建一个新的GZIPInputStream
- 将源流的数据复制到目标流
- 抛出IORuntimeException处理IO异常
# 4. 资源关闭
# close()
关闭所有流资源,实现了Closeable接口。
实现逻辑:
- 静默关闭目标流和源流
- 使用IoUtil.closeQuietly()方法确保资源安全关闭
# 🚀 使用示例
# 1. GZIP压缩示例
// 压缩单个文件
try (InputStream in = FileUtil.getInputStream("source.txt");
OutputStream out = FileUtil.getOutputStream("source.txt.gz")) {
Gzip.of(in, out).gzip();
Console.log("GZIP压缩完成!");
}
# 2. GZIP解压缩示例
// 解压缩GZIP文件
try (InputStream in = FileUtil.getInputStream("source.txt.gz");
OutputStream out = FileUtil.getOutputStream("source.txt")) {
Gzip.of(in, out).unGzip();
Console.log("GZIP解压缩完成!");
}
# 3. 链式调用示例
// 创建Gzip实例并立即执行压缩
try (InputStream in = FileUtil.getInputStream("source.txt");
OutputStream out = FileUtil.getOutputStream("source.txt.gz")) {
Gzip.of(in, out).gzip().close();
Console.log("GZIP压缩并关闭流完成!");
}
# 4. 与其他工具类结合使用
// 读取文件内容,压缩后输出到控制台
String content = FileUtil.readUtf8String("source.txt");
try (InputStream in = FileUtil.getInputStream("source.txt");
ByteArrayOutputStream out = new ByteArrayOutputStream()) {
Gzip.of(in, out).gzip();
byte[] compressed = out.toByteArray();
Console.log("原始内容长度:{}", content.length());
Console.log("压缩后长度:{}", compressed.length);
Console.log("压缩率:{:.2f}%", (1 - (double) compressed.length / content.length()) * 100);
}
# 🎯 设计优势
# 1. 简洁易用的API
- 采用链式调用设计,代码更加简洁流畅
- 封装了复杂的流处理逻辑,降低了使用门槛
- 统一的异常处理,避免了繁琐的try-catch代码
# 2. 自动资源管理
- 实现了Closeable接口,可以配合try-with-resources使用
- 自动关闭流资源,避免资源泄漏
- 静默关闭流,不会抛出额外异常
# 3. 灵活的流处理
- 支持普通流和GZIP流的自动转换
- 可以处理任意类型的输入输出流
- 支持链式调用,方便进行连续操作
# 4. 异常处理优化
- 将IOException转换为IORuntimeException,避免了受检异常的困扰
- 统一的异常类型,便于上层代码处理
- 提供了详细的异常信息,便于调试
# 📌 注意事项
# 1. 流的关闭
- 建议使用try-with-resources语句管理Gzip实例,确保资源正确关闭
- 如果不使用try-with-resources,需要手动调用close()方法
# 2. 压缩数据的完整性
- 调用gzip()方法后,会自动调用finish()方法完成压缩
- 确保在关闭流之前调用了gzip()或unGzip()方法,否则可能导致数据不完整
# 3. 性能考虑
- GZIP压缩会消耗一定的CPU资源,建议在后台线程中执行
- 对于超大文件,建议使用流式处理,避免一次性加载到内存
# 4. 编码问题
- GZIP压缩只处理二进制数据,不涉及字符编码
- 在压缩文本文件时,需要确保正确处理字符编码
# 5. 与JDK API的关系
Gzip类是对JDKGZIPInputStream和GZIPOutputStream的封装- 提供了更简洁的API,但底层实现仍然依赖JDK
# 🔄 与传统JDK方式的对比
# 1. 传统JDK方式(复杂)
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.GZIPOutputStream;
// 传统GZIP压缩方式
String sourceFile = "source.txt";
String targetFile = "source.txt.gz";
try (FileInputStream fis = new FileInputStream(sourceFile);
GZIPOutputStream gzos = new GZIPOutputStream(new FileOutputStream(targetFile))) {
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) > 0) {
gzos.write(buffer, 0, len);
}
gzos.finish();
Console.log("GZIP压缩完成!");
} catch (IOException e) {
e.printStackTrace();
}
# 2. Hutool方式(简洁)
import cn.hutool.v7.core.compress.Gzip;
import cn.hutool.v7.core.io.FileUtil;
import cn.hutool.v7.core.util.Console;
// Hutool GZIP压缩方式
String sourceFile = "source.txt";
String targetFile = "source.txt.gz";
try (InputStream in = FileUtil.getInputStream(sourceFile);
OutputStream out = FileUtil.getOutputStream(targetFile)) {
Gzip.of(in, out).gzip();
Console.log("GZIP压缩完成!");
}