<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 压缩流中如何压缩文件夹(包括子文件与子文件夹) 的实现原理与完整示例。

</aside>


🧠 一、核心原理:使用 ZipOutputStream

Java 原生库提供了 java.util.zip 包来进行 ZIP 压缩。

最重要的两个类是:

类名 作用
ZipOutputStream 用于将多个文件压缩为 .zip 文件的输出流
ZipEntry 表示压缩文件中的一个条目(文件或文件夹)

压缩文件夹的关键点在于:


🧩 二、基本步骤

  1. 创建输出流

    FileOutputStream fos = new FileOutputStream("output.zip");
    ZipOutputStream zos = new ZipOutputStream(fos);
    
  2. 递归添加文件或文件夹

  3. 关闭流

    zos.closeEntry();
    zos.close();
    

🧱 三、完整示例:压缩文件夹

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

public class ZipFolderExample {

    public static void main(String[] args) throws IOException {
        File sourceFolder = new File("D:/testFolder");   // 要压缩的文件夹
        File zipFile = new File("D:/output.zip");         // 压缩后的文件

        zipFolder(sourceFolder, zipFile);
        System.out.println("✅ 压缩完成: " + zipFile.getAbsolutePath());
    }

    public static void zipFolder(File sourceFolder, File zipFile) throws IOException {
        try (
            FileOutputStream fos = new FileOutputStream(zipFile);
            ZipOutputStream zos = new ZipOutputStream(fos)
        ) {
            String basePath = sourceFolder.getName() + "/";
            compress(sourceFolder, basePath, zos);
        }
    }

    private static void compress(File file, String path, ZipOutputStream zos) throws IOException {
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            if (files == null || files.length == 0) {
                // 空文件夹也要加一个 entry(必须以 / 结尾)
                zos.putNextEntry(new ZipEntry(path));
                zos.closeEntry();
            } else {
                for (File subFile : files) {
                    compress(subFile, path + subFile.getName() + (subFile.isDirectory() ? "/" : ""), zos);
                }
            }
        } else {
            // 压缩文件内容
            try (FileInputStream fis = new FileInputStream(file)) {
                zos.putNextEntry(new ZipEntry(path));
                byte[] buffer = new byte[4096];
                int len;
                while ((len = fis.read(buffer)) != -1) {
                    zos.write(buffer, 0, len);
                }
                zos.closeEntry();
            }
        }
    }
}