Несоответствие между размером ZipEntry для ZipInputStream и JarInputStream - PullRequest
5 голосов
/ 23 января 2012

У меня есть куча файлов изображений в zip-файле, который я читаю, используя ZipInputStream и перебирая ZipEntry из апплета.

   ZipInputStream zis = new ZipInputStream(in);
        ZipEntry ze = null;
        while ((ze = zis.getNextEntry()) != null) {
            htSizes.put(ze.getName(), new Integer((int) ze.getSize()));
            if (ze.isDirectory()) {
                continue;
            }
            int size = (int) ze.getSize();
            // -1 means unknown size.
            if (size == -1) {
                size = ((Integer) htSizes.get(ze.getName())).intValue();
            }
            byte[] b = new byte[(int) size];
            int rb = 0;
            int chunk = 0;
            while (((int) size - rb) > 0) {
                chunk = zis.read(b, rb, (int) size - rb);
                if (chunk == -1) {
                    break;
                }
                rb += chunk;
            }
            // add to internal resource hashtable
            htJarContents.put(ze.getName(), b);
        }

Однако, когда я помещаю эти изображения в банку со знаком, "ze.getSize()" приходит как -1, и файл изображения читается неправильно.

Может ли кто-нибудь помочь мне в этом.

Ответы [ 3 ]

4 голосов
/ 03 августа 2013

getSize () возвращает несжатый размер данных записи или -1, если неизвестно.

Поэтому, если возвращаемый размер отрицательный, добавьте его к 0xffffffffl, чтобы получить правильное значение.

Пример :

long size = ze.getSize();
if (size < 0) {
    size = 0xffffffffl + size ;
}

Ссылка : Возвращено отрицательное значение для ZipEntry.getSize ()

4 голосов
/ 23 января 2012

Да, -1 означает, что размер неизвестен - неясно, почему вы помещаете его в карту, а затем извлекаете его снова ..

В принципе, если размер неизвестен, вы должны сохранитьчтение буферов, пока read не вернет -1.Один простой способ - создать ByteArrayOutputStream и продолжить копирование из ZipEntry в него - затем, как только вы закончите чтение, просто получите массив байтов из ByteArrayOutputStream.Он будет обрабатывать любое необходимое изменение размера.

2 голосов
/ 23 января 2012

Этот вопрос похож на JarEntry.getSize () возвращает -1, когда файлы JAR открываются как InputStream с URL и ответ тот же.

В javadoc конкретно указано, что этот метод возвращает -1, если размер не может быть определен. И (по словам Тома Хотина) возможно, что возвращаемый размер неотрицателен ... и неверен.

Суть в том, что вам нужно обрабатывать сообщенный размер только как подсказку и считывать весь поток в расширяемый байтовый буфер (например, ByteArrayOutputStream).

...