Работа с Zip и GZip файлами в Java
Прошло некоторое время с тех пор, как я сделал Java I/O, и я не знаю последних "правильных" способов работы с Zip и GZip файлами. Мне не обязательно нужна полная рабочая демонстрация - я в первую очередь ищу подходящие интерфейсы и методы для использования. Да, я мог бы найти какой-либо случайный учебник по этому вопросу, но производительность - это проблема (эти файлы могут быть довольно большими), и мне действительно нужно использовать лучший инструмент для работы.
Основной процесс, который я буду выполнять:
- Загрузите кучу файлов (которые могут быть сжаты в zip, gzipped или оба) в папку temp.
- Добавьте все извлеченные файлы в новый zip файл в папке temp.
Входные файлы могут быть сжаты и архивированы более одного раза. Например, "полное извлечение" должно принимать любой из следующих входов (я не контролирую их) и оставляю foo.txt
:
-
foo.txt.gz
-
foo.txt.zip
-
foo.txt.gz.zip
-
foo.txt.zip.gz
- ...
-
foo.txt.gz.gz.gz.zip.gz.zip.zip.gz.gz
- ...
Тогда мне могут быть оставлены foo.txt
, bar.mp3
, baz.exe
- поэтому я просто добавлю их все в новый zip файл с каким-то общим именем.
Вопросы:
- С размером файла, представляющим потенциальную проблему, который (интерфейсы/классы/методы) следует использовать для быстрого:
- извлечь zip файлы?
- извлечь gzip файлы?
- написать zip файлы?
- Мне лучше сохранить отдельные извлеченные файлы в памяти перед тем, как записать обратно на диск? Или,
- Разве потенциально большие файлы делают эту плохую идею?
Ответы
Ответ 1
Обратите внимание, что библиотека TrueZip, предложенная ниже, была заменена на TrueVFS.
Я нашел полезную TrueZIP library. Он позволяет обрабатывать архивные файлы, как если бы они были просто другой файловой системой и использовать знакомые API-интерфейсы ввода-вывода Java.
В отличие от java.util.zip API, TrueZIP предоставляет произвольный доступ к содержимому архива, поэтому размер файла не должен вызывать беспокойства. Если я правильно помню, он будет обнаруживать архивные файлы и не пытаться избыточно сжимать их, когда вы помещаете их в архив.
Цитирование страницы TrueZIP:
API TrueZIP предоставляет замены для замены известных классов File, FileInputStream и FileOutputStream. Эта конструкция делает TrueZIP очень простой в использовании: все, что требуется для архивации большинства клиентских приложений, заключается в том, чтобы добавить несколько операторов импорта для пакета de.schlichtherle.io и добавить необходимые типы.
Теперь вы можете просто адресовать архивные файлы, такие как каталоги в имени пути. Например, имя пути "archive.zip/readme" обращается к записи архива "readme" в ZIP-архиве "archive.zip". Обратите внимание, что суффиксы имен файлов полностью настраиваются, и TrueZIP автоматически обнаруживает ложные срабатывания и возвращается назад, чтобы рассматривать их как обычные файлы или каталоги. Это работает рекурсивно, поэтому файл архива может быть даже заключен в другой файл архива, например, в "outer.zip/inner.zip/readme".
Ответ 2
Не сохраняйте все несжатые данные в памяти, или вы можете вырваться из кучи. Вам необходимо передать данные в файл при распаковке, а затем передать его обратно из файла, когда вы хотите создать свой последний zip файл.
Я раньше не делал файлы с zip файлами, но вот пример, который показывает, как распаковать gzipped файл:
import java.io.*;
import java.util.zip.*;
//unzipping a gzipped file
GZIPInputStream in = null;
OutputStream out = null;
try {
in = new GZIPInputStream(new FileInputStream("file.txt.gz"));
out = new FileOutputStream("file.txt");
byte[] buf = new byte[1024 * 4];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
}
catch (IOException e) {
e.printStackTrace();
}
finally {
if (in != null)
try {
in.close();
}
catch (IOException ignore) {
}
if (out != null)
try {
out.close();
}
catch (IOException ignore) {
}
}
Ответ 3
Там может быть библиотека где-то, чтобы сделать это легко.
Однако, если этого не происходит, вы все равно можете сделать это с помощью классов java.util.zip... используя ZipFile
или ZipInputStream
, вдоль с ZipEntry
для zip.
GZIPInputStream
может обернуть FileInputStream
для gzip, имея в виду, что gzip работает только с отдельными файлами.
Оба типа InputStreams также имеют соответствующие OutputStreams.
К сожалению, хотя я знаю об этих классах, я их никогда не использовал, поэтому я не могу советовать вам больше.
Изменить. У Zip-функций нет никакого способа добавления новых файлов в zip файл без повторного создания всего.