Ответ 1
Почему размер -1?
Вызов getNextEntry
в ZipInputStream
просто поместите курсор чтения в начало считываемой записи.
Размер (вместе с другими метаданными) сохраняется в конце фактических данных, поэтому он недоступен, когда курсор находится в начале.
Эта информация становится доступной только после того, как вы прочитаете все данные ввода или просто перейдете к следующей записи.
Например, переход к следующей записи:
// position at the start of the first entry
entry = zipIn.getNextEntry();
ZipEntry firstEntry = entry;
// size is not yet available
System.out.println("before " + firstEntry.getSize()); // prints -1
// position at the start of the second entry
entry = zipIn.getNextEntry();
// size is now available
System.out.println("after " + firstEntry.getSize()); // prints the size
или чтение всех входных данных:
// position at the start of the first entry
entry = zipIn.getNextEntry();
// size is not yet available
System.out.println("before " + entry.getSize()); // prints -1
// read the whole entry data
while(zipIn.read() != -1);
// size is now available
System.out.println("after " + entry.getSize()); // prints the size
Ваше недоразумение довольно распространено, и есть ряд сообщений об ошибках относительно этой проблемы (которые закрыты как "Не проблема" ), например JDK- 4079029, JDK-4113731, JDK-6491622.
Как уже упоминалось в отчетах об ошибках, вы можете использовать ZipFile
вместо ZipInputStream
, который позволит получить информацию о размере до доступа к входным данным; но для создания ZipFile
вам нужен File
(см. конструкторы) вместо байтового массива.
Например:
File file = new File( "test.zip" );
ZipFile zipFile = new ZipFile(file);
Enumeration enumeration = zipFile.entries();
while (enumeration.hasMoreElements()) {
ZipEntry zipEntry = (ZipEntry) enumeration.nextElement();
System.out.println(zipEntry.getSize()); // prints the size
}
Как получить данные из входного потока?
Если вы хотите проверить, равны ли распакованные данные исходным входным данным, вы можете читать из входного потока следующим образом:
byte[] output = new byte[input.length];
entry = zipIn.getNextEntry();
zipIn.read(output);
System.out.println("Are they equal? " + Arrays.equals(input, output));
// and if we want the size
zipIn.getNextEntry(); // or zipIn.read();
System.out.println("and the size is " + entry.getSize());
Теперь output
должен иметь тот же контент, что и input
.