You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用FileUtils.copyFile复制zip后解压报java.util.zip.ZipException异常

Java解压复制后的ZIP文件报错invalid distances set解决方案

异常信息

java.util.zip.ZipException: invalid distances set
    at java.base/java.util.zip.InflaterInputStream.read(InflaterInputStream.java:165)
    at java.base/java.util.zip.ZipInputStream.read(ZipInputStream.java:195)
    at java.base/java.io.FilterInputStream.read(FilterInputStream.java:107)

触发场景与前置验证

  • 文件先通过org.apache.commons.io.FileUtils.copyFile(File srcFile, File destFile)或Google Guava文件复制API完成复制,对复制后的目标文件执行解压操作时报错
  • 直接解压原始ZIP文件无异常,复制后的文件大小与原文件完全一致,可通过7Zip正常打开,内容无缺失
  • 故障复现使用的是大体积AdoptOpenJDK ZIP包,已排除解压逻辑本身的代码错误

根因说明

该问题是JDK内置java.util.zip工具包的兼容性限制导致:
AdoptOpenJDK的官方ZIP包多使用Deflate64或ZIP64扩展格式打包,JDK内置的zip解压实现默认不支持该类扩展压缩格式,而7Zip等第三方解压工具做了兼容,所以可以正常打开。文件复制操作本身不会修改包内压缩数据,只是触发了JDK解压逻辑对这类非标准压缩格式的校验报错。

修复方案

方案1:替换为兼容度更高的解压库

使用Apache Commons Compress库替代JDK内置的zip处理工具,该库原生支持Deflate64、ZIP64等扩展压缩格式,适配绝大多数场景的ZIP包解压需求。

方案2:调整JDK内置解压参数

如果必须使用JDK内置工具实现,构造ZipInputStream时显式传入开启nowrap模式的Inflater实例,适配扩展压缩格式:

// 解压核心代码调整示例
Inflater inflater = new Inflater(true);
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(destZipFile), StandardCharsets.UTF_8, inflater)) {
    // 原有解压逻辑保持不变
}

方案3:补充复制完整性校验

在文件复制完成后、执行解压前增加文件哈希校验,排除低概率的文件系统缓存未刷盘导致的文件不完整问题:

// 使用Apache Commons IO工具类做MD5校验
String srcFileMd5 = FileUtils.checksum(srcFile, new MD5Checksum()).toString();
String destFileMd5 = FileUtils.checksum(destFile, new MD5Checksum()).toString();
if (!srcFileMd5.equals(destFileMd5)) {
    throw new IOException("文件复制过程损坏,请重试");
}

内容的提问来源于stack exchange,提问作者micmei

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 12:09:04