简体   繁体   English

在Java上将文件解压缩时升级到1.8时出现的问题

[英]Issue while unzipping file on java upgrade to 1.8

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

I am using core java.util.zip classes. 我正在使用核心java.util.zip类。 Now while unzipping a client file using this code: 现在,使用以下代码解压缩客户端文件时:

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");
}

I am getting following error: 我收到以下错误:

invalid entry size (expected 1355916815 but got 5650884111 bytes) 

However the same code works fine in JDK 1.6. 但是,相同的代码在JDK 1.6中也可以正常工作。

I searched for all day but unable to find any occurrence that there are any changes corresponding to this code in Java JDK. 我整天都在搜索,但是找不到与Java JDK中的此代码相对应的任何更改的任何情况。

Please help me find suitable cause or links to support my findings. 请帮助我找到合适的原因或链接以支持我的发现。

Well, 1355916815 == (int) 5650884111L whereas 5650884111 is a number that can't be expressed using the four bytes reserved for the size field of the ZIP format. 好吧, 1355916815 == (int) 5650884111L5650884111是无法使用为ZIP格式的size字段保留的四个字节表示的数字。

Since you said, it worked in Java 6, which has no support for the ZIP64 format, we can conclude that you have a ZIP file that actually doesn't support files of 5650884111 bytes, but was generated by a tool which simply ignored that limitation and stored only the lower 32 bits of the actual size. 如您所言,它在不支持ZIP64格式的Java 6中工作,我们可以得出结论,您有一个ZIP文件,该文件实际上不支持5650884111字节的文件,而是由一个忽略了该限制的工具生成的并仅存储实际大小的低32位。

Apparently, the invalid file happened to work by accident due to the way, the extraction process was implemented. 显然,无效文件是由于这种方式偶然起作用的,提取过程得以实现。 It works by processing the compressed bytes and verifying the resulting number of bytes with the uncompressed size stored in the header, afterwards . 通过处理压缩后的字节, 然后使用头中存储的未压缩大小来验证所得的字节数,从而工作。 When the number of extracted bytes is stored in a 32 bit int variable and overflows silently during the extraction process and is only verified at the end, it appears to be the same as the stored 32 bit size. 当提取的字节数存储在32位int变量中并且在提取过程中无提示地溢出并且仅在最后进行验证时,它看起来与存储的32位大小相同。

Since in-between Java 6 and Java 8, ZIP64 support was added, I suppose, the decoder has been changed to use a long variable now, which is reasonable, as the same decoder can be used for processing both, old ZIP and ZIP64 files. 我想自从在Java 6和Java 8之间增加了对ZIP64的支持之后,我想现在解码器已更改为使用long变量,这很合理,因为同一解码器可用于处理旧的ZIP和ZIP64文件。 Then, the number of extracted bytes doesn't overflow anymore and it gets noticed that the stored size 1355916815 doesn't match the actually extracted number of 5650884111 bytes. 然后,提取的字节数不再溢出,并且注意到存储的大小1355916815与实际提取的5650884111字节数不匹配。

Unless you need to support Java 6, (re)creating the file as valid ZIP64 file should solve the problem. 除非您需要支持Java 6,(重新)将该文件创建为有效的ZIP64文件应该可以解决该问题。

( ZIP64 support has been added in Java 7 ) 在Java 7中添加了ZIP64支持

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM