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

如何解决Java读取含空目录的ZipInputStream时的ZipException异常

解决Java ZipInputStream读取Zip时的「Invalid Block lengths」异常

问题根源

Java自带的ZipInputStream对Zip格式的校验比较严格,当压缩包中包含名为.的根目录条目(属于非标准Zip结构)时,读取后续条目会触发格式校验失败,抛出ZipException。而Windows压缩工具对这类非标准结构的兼容性更强,所以能正常解压。

可行解决方案

方案一:跳过特殊目录条目,修正流位置

如果不想引入第三方库,可以手动跳过.目录对应的流数据块,避免后续流位置错乱:

try {
    ZipEntry ze = null;
    while ((ze = zin.getNextEntry()) != null) {
        // 跳过名为"."的特殊目录条目
        if (".".equals(ze.getName())) {
            // 消耗当前条目对应的流数据(即使是目录,也需要跳过空数据块)
            byte[] buffer = new byte[1024];
            while (zin.read(buffer) != -1) {
                // 仅消耗流,无业务操作
            }
            zin.closeEntry();
            continue;
        }
        if (!ze.isDirectory()) {
            // 这里处理文件条目逻辑
        }
        zin.closeEntry();
    }
} catch (ZipException ex) {
    // 异常处理逻辑
} finally {
    zin.close();
}

方案二:用Apache Commons Compress替代JDK实现

Apache Commons Compress对非标准Zip格式的兼容性更好,能自动处理这类特殊条目,无需手动操作:

  1. 先引入Maven依赖:
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-compress</artifactId>
    <version>1.24.0</version>
</dependency>
  1. 替换原有读取逻辑:
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;

// ...

try (ZipArchiveInputStream zais = new ZipArchiveInputStream(zin)) {
    ZipArchiveEntry zae = null;
    while ((zae = zais.getNextZipEntry()) != null) {
        if (!zae.isDirectory()) {
            // 处理文件条目逻辑
        }
    }
} catch (IOException ex) {
    // 异常处理逻辑
}

该库支持直接从输入流读取,不需要将文件落地到本地文件系统,完全符合你的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 08:50:22