Java原生zip/jar包可实现轻量跨平台压缩解压,核心是ZipOutputStream/InputStream流式处理、资源管理、中文路径兼容及路径穿越防护。

Java 自带的 java.util.zip 和 java.util.jar 包已足够支撑一个轻量、稳定、跨平台的文件压缩解压工具,无需第三方库也能完成 ZIP 格式的核心功能。关键在于理解流式处理逻辑、正确管理资源、处理中文路径和异常边界。
ZIP 压缩:递归遍历 + 套娃输出流
压缩本质是把多个文件/目录按 ZIP 格式规范写入一个输出流。核心是 ZipOutputStream,它需要配合 FileInputStream 逐个写入条目(ZipEntry)。
- 对每个待压缩文件或目录,递归获取所有子文件,生成相对路径(避免绝对路径导致解压乱套)
- 为每个文件创建
ZipEntry,设置名称(注意用entry.setName(...)而非构造器传参,兼容中文路径) - 调用
putNextEntry()后写入字节,再closeEntry()—— 忘记后者会导致 ZIP 损坏 - 使用 try-with-resources 确保
ZipOutputStream和底层FileOutputStream正确关闭
ZIP 解压:按条目还原路径 + 自动建目录
解压是压缩的逆过程:读取 ZIP 条目 → 创建对应文件或目录 → 写入内容。难点在于路径安全与目录预创建。
- 用
ZipInputStream遍历ZipEntry,通过getName()获取原始路径 - 对每个条目,先判断是否为目录(
isDirectory()),是则用Files.createDirectories()创建完整路径 - 非目录条目需确保其父目录存在(
Files.createDirectories(entry.getParent())),再用Files.write()或流式写入 - 务必过滤掉路径中含
"../"的条目(防止路径穿越漏洞),例如:if (entryName.contains("..")) throw new IOException("Unsafe path");
支持中文名与跨平台兼容性
JDK 7+ 默认使用 UTF-8 编码处理 ZIP 条目名,但旧版 JDK 或某些 Windows 工具仍用 GBK,导致中文乱码。稳妥做法:
立即学习“Java免费学习笔记(深入)”;
- 压缩时显式设置
ZipOutputStream的编码(需反射或使用org.apache.commons.compress等增强库) - 更实用的方案:压缩端统一用 UTF-8,解压端对
ZipEntry.getName()做容错解析——若默认解码为乱码(如出现 ),尝试用 GBK 重新解码字节数组 - 避免在文件名中使用控制字符、空格、斜杠等特殊符号,减少兼容性风险
扩展思路:支持多格式与进度反馈
纯 ZIP 功能够用原生 API 实现,若需支持 TAR、GZ、7z 等,建议引入成熟库:
-
Apache Commons Compress:统一接口支持 ZIP/TAR/GZ/BZIP2/AR/LZH 等,API 清晰,文档完善 -
TrueZIP(已归档)或zip4j:适合需密码保护 ZIP 的场景(原生 ZIP 不支持加密) - 添加进度反馈?可包装
InputStream/OutputStream,统计已处理字节数,结合总大小计算百分比,通过回调通知 UI 层










