Java中用ZipOutputStream压缩多文件的核心步骤是:为每个文件创建ZipEntry,调用putNextEntry()开启条目,写入内容后必须调用closeEntry();需用try-with-resources或手动close释放资源,并注意相对路径、空目录显式添加及UTF-8中文名支持(JDK11+可用带Charset构造器)。

用 ZipOutputStream 把多个文件写入一个 ZIP 包,核心是:为每个文件创建一个 ZipEntry,调用 putNextEntry(),再把文件内容写进去,最后调用 closeEntry()。整个过程必须在 try-with-resources 或手动 close 保证资源释放。
准备文件列表并打开 ZipOutputStream
先准备好要压缩的文件路径(可以是 File 或 Path),然后用 FileOutputStream 包裹 ZipOutputStream:
try (FileOutputStream fos = new FileOutputStream("output.zip");
ZipOutputStream zos = new ZipOutputStream(fos)) {
// 后续操作
}
逐个添加文件(含路径处理)
对每个待压缩文件:
- 用其相对路径(避免绝对路径如
/home/user/a.txt)构造ZipEntry,否则解压可能出错或覆盖系统路径 - 调用
zos.putNextEntry(entry)开启该条目写入 - 用普通字节流(如
Files.newInputStream())读取源文件,写入zos - 必须调用
zos.closeEntry(),否则 ZIP 结构不完整,部分工具无法识别
for (Path file : filesToZip) {
String entryName = getRelativePath(rootDir, file); // 如 "docs/readme.md"
ZipEntry entry = new ZipEntry(entryName);
zos.putNextEntry(entry);
Files.copy(file, zos); // 自动完成读写
zos.closeEntry(); // 关键!不能省
}
注意文件夹与空目录
ZipOutputStream 不会自动包含空目录。如需保留目录结构,得显式添加目录类型的 ZipEntry(名称以 / 结尾,且 setSize(0)):
立即学习“Java免费学习笔记(深入)”;
ZipEntry dirEntry = new ZipEntry("subdir/");
dirEntry.setSize(0);
zos.putNextEntry(dirEntry);
zos.closeEntry();
编码与中文文件名问题
标准 ZipOutputStream 使用 IBM437 编码,中文名会乱码。解决办法:
- JDK 7+ 推荐用
java.util.zip.ZipOutputStream配合sun.nio.cs.StandardCharsets.UTF_8—— 但不跨平台 - 更稳妥:用 Apache Commons Compress 或 TrueZIP,它们原生支持 UTF-8 文件名
- 若坚持用原生 API,可考虑
new ZipOutputStream(fos, StandardCharsets.UTF_8)(JDK 11+ 支持)


















