извлечение содержимого записей ZipFile при чтении из byte [] (Java) - PullRequest
4 голосов
/ 07 октября 2009

У меня есть zip-файл, содержимое которого представлено в виде байта [] , но исходный объект файла недоступен . Я хочу прочитать содержимое каждой записи. Я могу создать ZipInputStream из ByteArrayInputStream байтов и могу читать записи и их имена. Однако я не вижу простого способа извлечь содержимое каждой записи.

(Я смотрел на Apache Commons, но не вижу там и легкого пути).

ОБНОВЛЕНИЕ @ Код Рича, похоже, решает проблему, спасибо

QUERY почему оба примера имеют множитель * 4 (128/512 и 1024 * 4)?

Ответы [ 3 ]

6 голосов
/ 07 октября 2009

Если вы хотите обработать вложенные записи zip из потока, см. этот ответ для идей. Поскольку внутренние записи перечислены последовательно, их можно обработать, получив размер каждой записи и считав столько байтов из потока.

Обновлен с примером, который копирует каждую запись в стандартный выход:

ZipInputStream is;//obtained earlier

ZipEntry entry = is.getNextEntry();

while(entry != null) {
    copyStream(is, out, entry);

    entry = is.getNextEntry();
}
...

private static void copyStream(InputStream in, OutputStream out,
        ZipEntry entry) throws IOException {
    byte[] buffer = new byte[1024 * 4];
    long count = 0;
    int n = 0;
    long size = entry.getSize();
    while (-1 != (n = in.read(buffer)) && count < size) {
        out.write(buffer, 0, n);
        count += n;
    }
}
0 голосов
/ 07 октября 2009

Немного сложно вычислить начало следующего ZipEntry. Пожалуйста, смотрите этот пример, включенный в JDK 6,

public static void main(String[] args) {
    try {
        ZipInputStream is = new ZipInputStream(System.in);
        ZipEntry ze;
        byte[] buf = new byte[128];
        int len;

        while ((ze = is.getNextEntry()) != null) {
            System.out.println("----------- " + ze);

            // Determine the number of bytes to skip and skip them.
            int skip = (int)ze.getSize() - 128;
            while (skip > 0) {
                skip -= is.skip(Math.min(skip, 512));
            }

            // Read the remaining bytes and if it's printable, print them.
            out: while ((len = is.read(buf)) >= 0) {
                for (int i=0; i<len; i++) {
                    if ((buf[i]&0xFF) >= 0x80) {
                        System.out.println("**** UNPRINTABLE ****");

                        // This isn't really necessary since getNextEntry()
                        // automatically calls it.
                        is.closeEntry();

                        // Get the next zip entry.
                        break out;
                    }
                }
                System.out.write(buf, 0, len);
            }
        }
        is.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}
0 голосов
/ 07 октября 2009

Он фактически использует ZipInputStream в качестве InputStream (но не закрывайте его в конце каждой записи).

...