Java中保持ZIP目录层级的关键是:压缩时用相对路径构造ZipEntry(含空目录),解压时校验路径合法性并自动创建父目录;需显式指定UTF-8编码、正确关闭流、防范路径穿越攻击。

Java 中用 IO 流压缩或解压 ZIP 文件时,保持目录层级结构的关键在于:正确构造 ZipEntry 的名称(即路径),并按需创建中间目录。不是简单拼接文件名,而是使用相对路径、逐级解析、安全校验。
压缩时保留目录结构:用相对路径生成 ZipEntry
压缩一个文件夹时,不能只取文件名,而要计算它相对于源根目录的**相对路径**,作为 ZipEntry 的名字。
- 例如源目录为
D:projectsrcMain.java,以D:project为根压缩,则ZipEntry名应为src/Main.java(Windows 下用/分隔,ZIP 标准要求正斜杠) - 空文件夹也要显式添加:调用
zos.putNextEntry(new ZipEntry("src/")),末尾带斜杠表示目录 - 推荐递归遍历 + 路径裁剪方式,避免硬编码绝对路径;可借助
Paths.get(src).relativize(Paths.get(file))获取相对路径
解压时还原目录结构:按 entry.getName() 创建完整路径
解压时不能直接用 entry.getName() 创建 File 对象(有路径穿越风险),而应做两件事:路径合法性校验 + 父目录自动创建。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 先检查
entry.getName()是否含../、..或以/开头等危险模式,拒绝非法条目 - 将
entry.getName()拼到目标目录后,调用file.getParentFile().mkdirs()确保所有上级目录存在 - 如果是目录条目(
entry.isDirectory()),则仅创建文件夹;否则创建文件并写入内容
编码与流管理细节不能忽略
中文路径乱码和资源泄漏是常见问题,直接影响结构还原是否成功。
立即学习“Java免费学习笔记(深入)”;
- 构造
ZipInputStream和ZipOutputStream时,显式传入StandardCharsets.UTF_8,避免默认平台编码导致路径解析错误 - 必须使用
try-with-resources或手动closeEntry()+close(),否则部分条目可能未写入或未释放,造成解压后缺目录或文件不全 - 写文件建议套一层
BufferedOutputStream,提升大文件解压性能;读取时也推荐用缓冲数组(如new byte[8192])而非单字节循环
安全提醒:防止路径穿越攻击
攻击者可能在 ZIP 包中构造恶意条目名(如 ../../etc/passwd),直接拼接会覆盖系统文件。
- 解压前对每个
entry.getName()做标准化处理:Paths.get(entry.getName()).normalize().toString() - 检查标准化后路径是否仍以
..开头,或是否包含:\、:/等绝对标识 - 只允许纯相对路径(如
a/b/c.txt、lib/),其余一律跳过或抛异常

















