压缩流

<aside> <img src="notion://custom_emoji/c233e7bc-acd0-812b-a811-00030dcd1edc/29e3e7bc-acd0-808e-ac64-007a3fac687d" alt="notion://custom_emoji/c233e7bc-acd0-812b-a811-00030dcd1edc/29e3e7bc-acd0-808e-ac64-007a3fac687d" width="40px" />

在 Java 中,压缩流是一种特殊的I/O流(装饰器流),它允许你在读取或写入数据的同时,自动对数据进行压缩或解压缩。这对于节省存储空间或减少网络传输数据量非常有用。

</aside>

这些功能主要由 java.util.zip 包提供。我们主要关注两种最常见的压缩格式:GZIPZIP


🚀 核心概念:装饰器模式

你需要理解,Java 的压缩流是装饰器(Decorator)。它们不能独立工作,必须“包装”在另一个基础流(如 FileInputStreamFileOutputStream)之上。


1. GZIP 压缩流(单个文件或数据流)

GZIP (GNU zip) 是一种常见的压缩格式,通常用于压缩单个文件单个数据流。在 Unix/Linux 系统中,你经常会看到 .gz 后缀的文件。

📦 GZIPOutputStream:压缩数据

它用于将数据压缩为 GZIP 格式,并写入到底层输出流。

关键点:

示例:压缩一个文件

import java.io.*;
import java.util.zip.GZIPOutputStream;

public class GzipCompress {
    public static void main(String[] args) {
        String sourceFile = "source.txt";
        String compressedFile = "source.txt.gz";

        // 使用 try-with-resources 自动关闭流
        try (
            // 1. 创建一个文件输入流来读取源文件
            FileInputStream fis = new FileInputStream(sourceFile);
            // 2. 创建一个文件输出流来写入压缩文件
            FileOutputStream fos = new FileOutputStream(compressedFile);
            // 3. 创建 GZIP 输出流来包装文件输出流
            GZIPOutputStream gzipOS = new GZIPOutputStream(fos)
        ) {
            byte[] buffer = new byte[8192]; // 缓冲区
            int bytesRead;

            // 4. 从源文件读取数据,并写入 GZIP 流
            while ((bytesRead = fis.read(buffer)) != -1) {
                gzipOS.write(buffer, 0, bytesRead);
            }

            System.out.println("文件压缩成功!");

        } catch (IOException e) {
            e.printStackTrace();
        }
        // GZIPOutputStream 和 FileOutputStream 在 try 块结束时会自动关闭
    }
}

📥 GZIPInputStream:解压数据

它用于从一个底层输入流中读取 GZIP 格式的压缩数据,并在读取时自动解压。