推荐用java.util.zip.zipoutputstream配合fileinputstream打包zip,注意路径用正斜杠、中文名需utf-8编码、空目录单独添加结尾为/的zipentry,并用try-with-resources确保资源关闭。

Java 中把多个文件打包成 ZIP,推荐用 java.util.zip 包里的 ZipOutputStream,配合 FileInputStream 逐个写入,同时注意路径处理、中文文件名和资源关闭。
准备文件列表并创建 ZIP 输出流
先准备好要压缩的 File 对象集合(支持单个文件或整个目录),再用 FileOutputStream 创建 ZipOutputStream。建议指定 UTF-8 编码防止中文乱码(JDK 7+ 默认支持,但某些旧环境需确保系统编码或显式设置):
- 使用
try-with-resources自动关闭流,避免资源泄漏 - ZIP 条目路径必须用正斜杠
/分隔,不能用系统默认分隔符(如 Windows 的\) - 空目录需单独添加一个以
/结尾的ZipEntry
逐个写入文件到 ZIP 中
对每个待压缩文件,构造相对路径的 ZipEntry(避免绝对路径泄露本地信息),然后读取文件内容写入 ZipOutputStream:
- 若源是目录,递归遍历子文件,entry 名称 = 目录内相对路径(如
docs/readme.txt) - 调用
zos.putNextEntry(entry)后才能写内容,写完必须调用zos.closeEntry() - 小文件可直接用
Files.readAllBytes();大文件建议用缓冲字节数组(如 8KB)分块读写
处理中文文件名和兼容性
JDK 7 引入了 ZipOutputStream 对 UTF-8 文件名的原生支持,但部分老版本或解压工具(如早期 Windows 自带解压器)仍可能显示乱码:
- 确保 JVM 启动参数含
-Dfile.encoding=UTF-8(非必需但更稳妥) - 避免在 entry 名中使用控制字符或非法路径符号(如
../、NUL) - 如需最大兼容性,可对文件名做 ASCII 转义(不推荐,影响可读性),一般项目用标准 UTF-8 即可
简单示例代码片段
以下是一个压缩多个文件(含子目录)的核心逻辑:
try (ZipOutputStream zos = new ZipOutputStream(
new FileOutputStream("output.zip"), StandardCharsets.UTF_8)) {
for (File file : filesToZip) {
addFileToZip(file, file.getName(), zos);
}
}
// 递归方法:file 是源文件/目录,entryName 是 ZIP 内路径
void addFileToZip(File file, String entryName, ZipOutputStream zos) throws IOException {
if (file.isDirectory()) {
if (!entryName.endsWith("/")) entryName += "/";
zos.putNextEntry(new ZipEntry(entryName));
zos.closeEntry();
for (File sub : file.listFiles()) {
addFileToZip(sub, entryName + sub.getName(), zos);
}
} else {
zos.putNextEntry(new ZipEntry(entryName));
Files.copy(file.toPath(), zos);
zos.closeEntry();
}
}
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











