Каков самый быстрый способ извлечь 1 файл из zip файла, который содержит много файлов?
Я попробовал пакет java.util.zip, он слишком медленный.
Затем я нашел LZMA SDK и 7z jbinding, но им также ничего не хватает.
LZMA SDK не предоставляет своего рода документацию/учебник о том, как использовать, это очень неприятно. Нет javadoc.
В то время как 7z jbinding не обеспечивает простой способ извлечь только 1 файл, однако, он предоставляет только способ извлечь все содержимое zip файла. Более того, он не предоставляет способ указать место для размещения распакованного файла.
Любая идея, пожалуйста.
Ответы
Ответ 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
, чтобы гарантировать, что файл будет закрыт после использования.