0
Java version "1.8.0_40"
Java(TM) SE Runtime Environment (build 1.8.0_40-b26)

我正在使用核心java.util.zip课程。现在在使用以下代码解压缩客户端文件时:

public static InputStream unzip(String file,InputStream zip)
        throws IOException {
    file = file.toLowerCase();
    ZipInputStream zin = new ZipInputStream(new BufferedInputStream(zip));
    ZipEntry ze;
    while( (ze = zin.getNextEntry()) != null ) {
        if ( ze.getName().toLowerCase().equals(file) )
            return zin;
    }
    throw new RuntimeException(file+" not found in zip");
}

我收到以下错误:

invalid entry size (expected 1355916815 but got 5650884111 bytes) 

然而,相同的代码在 JDK 1.6 中运行良好。

我搜索了一整天,但找不到任何与 Java JDK 中的代码对应的任何更改。

请帮助我找到合适的原因或链接来支持我的发现。

4

1 回答 1

1

好吧,1355916815 == (int) 5650884111Lwhile5650884111是一个无法使用为 ZIP 格式的大小字段保留的四个字节来表示的数字。

既然你说它在不支持 ZIP64 格式的 Java 6 中工作,我们可以得出结论,你有一个 ZIP 文件实际上不支持5650884111字节文件,但它是由一个简单地忽略该限制的工具生成的,并且仅存储实际大小的低 32 位。

显然,由于执行提取过程的方式,无效文件碰巧起作用了。它的工作原理是处理压缩字节,然后使用存储在标头中的未压缩大小验证生成的字节数。当提取的字节数存储在 32 位int变量中并在提取过程中静默溢出并且仅在最后进行验证时,它似乎与存储的 32 位大小相同。

由于在 Java 6 和 Java 8 之间添加了 ZIP64 支持,我想现在解码器已更改为使用long变量,这是合理的,因为可以使用同一个解码器来处理旧的 ZIP 和 ZIP64 文件。然后,提取的字节数不再溢出,并且注意到存储的大小与实际提取的字节1355916815数不匹配。5650884111

除非您需要支持 Java 6,否则(重新)将文件创建为有效的 ZIP64 文件应该可以解决问题。

Java 7 中添加了 ZIP64 支持

于 2016-05-31T10:54:37.130 回答