2016-05-31 9 views
0
Java version "1.8.0_40" 
Java(TM) SE Runtime Environment (build 1.8.0_40-b26) 

Я использую основные классы java.util.zip. Теперь во время распаковки файла клиента, используя этот код:Проблема при распаковке файла с обновлением java до 1,8

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

Ну, 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, (re) создание файла, так как действительный файл ZIP64 должен решить проблему.

(ZIP64 support has been added in Java 7)