将java上的文件解压缩到1.8时发出问题

时间:2016-05-31 10:03:20

标签: java java-8 jdk1.6 zipinputstream

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中找不到与此代码相对应的任何更改。

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

1 个答案:

答案 0 :(得分:1)

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

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

显然,无效文件由于方式而偶然发生,提取过程已实施。它的工作原理是处理压缩的字节并验证结果的字节数,其中未压缩的大小存储在标题中,之后。当提取的字节数存储在32位int变量中并在提取过程中静默溢出并且仅在结束时验证时,它看起来与存储的32位大小相同。

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

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

ZIP64 support has been added in Java 7