Подтвердить что ты не робот

Каков самый быстрый способ извлечь 1 файл из zip файла, который содержит много файлов?

Я попробовал пакет java.util.zip, он слишком медленный.

Затем я нашел LZMA SDK и 7z jbinding, но им также ничего не хватает. LZMA SDK не предоставляет своего рода документацию/учебник о том, как использовать, это очень неприятно. Нет javadoc.

В то время как 7z jbinding не обеспечивает простой способ извлечь только 1 файл, однако, он предоставляет только способ извлечь все содержимое zip файла. Более того, он не предоставляет способ указать место для размещения распакованного файла.

Любая идея, пожалуйста.

4b9b3361

Ответ 1

Как выглядит ваш код с java.util.zip и насколько большой размер zip файла вы имеете в виду?

Я могу извлечь 4MB-запись из 200-мегабайтного zip файла с 1800 записями примерно через секунду:

OutputStream out = new FileOutputStream("your.file");
FileInputStream fin = new FileInputStream("your.zip");
BufferedInputStream bin = new BufferedInputStream(fin);
ZipInputStream zin = new ZipInputStream(bin);
ZipEntry ze = null;
while ((ze = zin.getNextEntry()) != null) {
    if (ze.getName().equals("your.file")) {
        byte[] buffer = new byte[8192];
        int len;
        while ((len = zin.read(buffer)) != -1) {
            out.write(buffer, 0, len);
        }
        out.close();
        break;
    }
}

Ответ 2

Я не сравнивал скорость, но с java 7 или выше, я извлекаю файл следующим образом.
Я бы предположил, что это быстрее, чем ZipFile API:

Краткий пример: извлечение META-INF/MANIFEST.MF из zip файла test.zip:

// file to extract from zip file
String file = "MANIFEST.MF";
// location to extract the file to
File outputLocation = new File("D:/temp/", file);
// path to the zip file
Path zipFile = Paths.get("D:/temp/test.zip");

// load zip file as filesystem
try (FileSystem fileSystem = FileSystems.newFileSystem(zipFile, null)) {
    // copy file from zip file to output location
    Path source = fileSystem.getPath("META-INF/" + file);
    Files.copy(source, outputLocation.toPath());
}

Ответ 3

Используйте ZipFile, а не ZipInputStream.

Хотя документация не указывает это (это в документах для JarFile), для чтения файла следует использовать операции с произвольным доступом. Поскольку ZIP файл содержит каталог в известном месте, это означает, что LOT меньше IO должно произойти, чтобы найти конкретный файл.

Некоторые предостережения: насколько я знаю, реализация Sun использует файл с отображением памяти. Это означает, что ваше виртуальное адресное пространство должно быть достаточно большим для хранения файла, а также всего остального в вашей JVM. Это может быть проблемой для 32-разрядного сервера. С другой стороны, он может быть достаточно умным, чтобы избежать сопоставления памяти на 32-битной карте памяти или только в каталоге; Я не пробовал.

Кроме того, если вы используете несколько файлов, обязательно используйте try/finally, чтобы гарантировать, что файл будет закрыт после использования.