Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Несоответствие между размером ZipEntry для ZipInputStream и JarInputStream

Автор вопроса: Deepak ChaudhryОтветов: 3

У меня есть куча файлов изображений в 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, и файл изображения читается неправильно.

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

  • Вы действительно не должны усекать размер до int. Также см. ответ @JonSkeet ниже. Perception 23.01.2012
  • возможный дубликат JarEntry .getSize() возвращает -1, когда файлы jar открываются как InputStream из URL Stephen C 23.01.2012
  • Почему бы просто не получить входной поток сжатого изображения и не передать его ImageIO.read(InputStream)? Andrew Thompson 24.01.2012

appletjavajarzipsigned-applet

Ответы

Ответ 1 · рейтинг 4 · Jon Skeet

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

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

Ответ 2 · рейтинг 3 · Areeg Samir

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

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

Пример:

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

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

Ответ 3 · рейтинг 2 · Stephen C

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

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

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

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы