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中找不到与此代码相对应的任何更改。
请帮我找到合适的原因或链接以支持我的发现。
答案 0 :(得分:1)
好吧,1355916815 == (int) 5650884111L
而5650884111
是一个无法使用为ZIP格式的大小字段保留的四个字节来表示的数字。
既然你说它在Java 6中工作,它不支持ZIP64格式,我们可以得出结论你有一个ZIP文件实际上不支持5650884111
字节的文件,但是由一个工具,它只是忽略了这个限制,只存储了实际大小的低32位。
显然,无效文件由于方式而偶然发生,提取过程已实施。它的工作原理是处理压缩的字节并验证结果的字节数,其中未压缩的大小存储在标题中,之后。当提取的字节数存储在32位int
变量中并在提取过程中静默溢出并且仅在结束时验证时,它看起来与存储的32位大小相同。
由于在Java 6和Java 8之间添加了ZIP64支持,我想,现在解码器已被更改为使用long
变量,这是合理的,因为可以使用相同的解码器进行处理旧的ZIP和ZIP64文件。然后,提取的字节数不再溢出,并且注意到存储的大小1355916815
与实际提取的5650884111
字节数不匹配。
除非您需要支持Java 6,否则(重新)将文件创建为有效的ZIP64文件应该可以解决问题。