GZIPInputStream 和 GZIPOutputStream 是 Java 中用于实时压缩与解压 GZIP 数据流的核心类,分别包装输入/输出流实现字节级处理,不直接操作文件,需配合 ByteArrayOutputStream、FileInputStream 等使用,并注意编码、异常及流关闭。

GZIPInputStream 和 GZIPOutputStream 是 Java 标准库(java.util.zip)中用于处理 GZIP 格式数据流的两个核心类,它们不直接操作文件,而是包装已有的输入/输出流,实现字节级的实时压缩与解压。
一、GZIPOutputStream:写入时自动压缩
它把原始数据“套上 GZIP 头部+压缩内容”后写入底层流。关键点是:它只做压缩,不负责写文件;你得自己提供目标输出流(比如 FileOutputStream 或 ByteArrayOutputStream)。
使用示例(压缩字符串到字节数组):
String original = "Hello, GZIP!";
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (GZIPOutputStream gzos = new GZIPOutputStream(baos)) {
gzos.write(original.getBytes(StandardCharsets.UTF_8));
}
byte[] compressed = baos.toByteArray(); // 得到 gzip 格式字节
注意:
• 必须调用 close() 或用 try-with-resources —— 否则压缩尾部(如校验和、长度)可能不完整;
• 默认使用 DEFLATE 算法,压缩级别为 DEFAULT_COMPRESSION(6),也可传入自定义级别(0~9);
• 不支持多文件打包(那是 TarArchiveOutputStream 的事)。
二、GZIPInputStream:读取时自动解压
它从底层输入流中识别 GZIP 头部,透明地解压后续内容。只要源数据是合法 gzip 格式(比如由 GZIPOutputStream 生成,或 Linux 的 gzip 命令生成的 .gz 文件),就能正确还原。
使用示例(从字节数组解压回字符串):
ByteArrayInputStream bais = new ByteArrayInputStream(compressed);
try (GZIPInputStream gzis = new GZIPInputStream(bais)) {
String decompressed = new String(gzis.readAllBytes(), StandardCharsets.UTF_8);
System.out.println(decompressed); // 输出:Hello, GZIP!
}
注意:
• 如果输入流开头不是合法 GZIP 头(0x1f 0x8b),会抛 IOException;
• 它只解压一个 gzip 数据块 —— 不支持串联多个 gzip 流(除非启用 inflater.setInput(...) 手动控制,但非常规用法);
• 解压过程是懒加载的,read() 调用时才真正解码,内存占用相对可控。
三、常见组合场景
• 压缩并保存为 .gz 文件:
→ 用 FileOutputStream 包装 GZIPOutputStream,再 write 写入原始数据。
• 读取本地 .gz 文件:
→ 用 FileInputStream 包装 GZIPInputStream,再 read 获取解压后内容。
• 网络传输压缩数据:
→ HTTP 响应体用 GZIPOutputStream 包装 response.getOutputStream();客户端收到后用 GZIPInputStream 解包。
• 内存中压缩/解压(无磁盘 IO):
→ 组合 ByteArrayInputStream / ByteArrayOutputStream,适合缓存、序列化优化等场景。
四、注意事项与避坑点
• 字符编码要显式指定:不要用 String.getBytes() 默认平台编码,务必用 StandardCharsets.UTF_8 等明确值;
• 流必须成对使用:用 GZIPOutputStream 压缩的数据,才能被 GZIPInputStream 正确解压;普通 ZIP 或 ZLIB 流不兼容;
• 不处理文件名、时间戳等元信息:GZIP 格式本身支持这些字段,但 Java 的这两个类默认忽略,只关注压缩数据体;
• 大文件建议配合缓冲:直接 read/write 单字节效率低,推荐 wrap BufferedInputStream/BufferedOutputStream;
• 异常需捕获 IOException:包括流关闭失败、数据损坏、内存不足等,生产环境应妥善处理。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











