распаковать файл .gz в пакетном режиме

У меня есть 100 файлов .gz, которые мне нужно распаковать. у меня есть пара вопросов

а) Я использую код, указанный на http://www.roseindia.net/java/beginners/JavaUncompress.shtml, чтобы распаковать файл .gz. Он работает нормально. Задание: есть ли способ получить имя заархивированного файла. Я знаю, что класс Zip Java дает перечисление входного файла для работы. Это может дать мне имя файла, размер и т. д., хранящиеся в файле .zip. Но есть ли у нас то же самое для файлов .gz или имя файла такое же, как имя файла .gz с удаленным .gz.

б) есть ли еще один элегантный способ распаковать файл .gz, вызвав служебную функцию в коде Java. Например, вызов приложения 7-zip из вашего класса Java. Тогда мне не нужно беспокоиться о потоке ввода/вывода.

Заранее спасибо. Капил


person Kapil D    schedule 23.05.2009    source источник


Ответы (6)


а) Zip — это формат архива, а gzip — нет. Таким образом, итератор записи не имеет особого смысла, если (например) ваши gz-файлы не являются сжатыми файлами tar. То, что вы хотите, вероятно:

File outFile = new File(infile.getParent(), infile.getName().replaceAll("\\.gz$", ""));

б) Вы хотите распаковать только файлы? Если нет, вы можете использовать GZIPInputStream и читать файлы напрямую, то есть без промежуточной распаковки.

Но ладно. Допустим, вы действительно только хотите распаковать файлы. Если это так, вы, вероятно, могли бы использовать это:

public static File unGzip(File infile, boolean deleteGzipfileOnSuccess) throws IOException {
    GZIPInputStream gin = new GZIPInputStream(new FileInputStream(infile));
    FileOutputStream fos = null;
    try {
        File outFile = new File(infile.getParent(), infile.getName().replaceAll("\\.gz$", ""));
        fos = new FileOutputStream(outFile);
        byte[] buf = new byte[100000];
        int len;
        while ((len = gin.read(buf)) > 0) {
            fos.write(buf, 0, len);
        }

        fos.close();
        if (deleteGzipfileOnSuccess) {
            infile.delete();
        }
        return outFile; 
    } finally {
        if (gin != null) {
            gin.close();    
        }
        if (fos != null) {
            fos.close();    
        }
    }       
}
person fredarin    schedule 24.05.2009
comment
Привет, могу ли я прочитать файлы без распаковки. Я хочу что-то вроде чтения построчно. И файлы могут иметь не только 80 символов в длину/строку. BufferedReader — это то, что у меня работало. Но у него нет конструктора для GzInputStream. - person Kapil D; 15.06.2009
comment
Я бы написал то, что хочу, например: BufferedReader in = new BufferedReader(new GzipFileReader(file)); Затем реализуйте GzipFileReader как расширение Reader. - person fredarin; 18.06.2009

Что касается A, команда gunzip создает несжатый файл с исходным именем без суффикса .gz. См. справочную страницу.

Что касается B, вам нужен именно gunzip или подойдет другой алгоритм сжатия? Существует java-порт алгоритма сжатия LZMA, который используется 7zip для создания .7z файлов, но он не будет обрабатывать файлы .gz.

person Paul Morie    schedule 23.05.2009

Если у вас есть фиксированное количество файлов, которые нужно распаковать один раз, почему бы вам не использовать для этого существующие инструменты? Как заметил Пол Мори, gunzip может это сделать: for i in *.gz; do gunzip $i; done И он автоматически назвал бы их, лишив .gz$

В Windows попробуйте winrar, возможно, или gunzip с http://unxutils.sf.net

person alamar    schedule 23.05.2009

GZip обычно используется только для отдельных файлов, поэтому он обычно не содержит информации об отдельных файлах. Чтобы объединить несколько файлов в один сжатый архив, они сначала объединяются в несжатый файл Tar (с информацией об отдельном содержимом), а затем сжимаются как один файл. Эта комбинация называется Tarball.

Существуют библиотеки для извлечения информации об отдельных файлах из Tar, как и в ZipEntries. Один пример. Сначала вам нужно извлечь файл .gz во временный файл, чтобы использовать его или, по крайней мере, передать GZipInputStream в библиотеку Tar.

Вы также можете вызвать 7-Zip из командной строки, используя Java. Синтаксис командной строки 7-Zip приведен здесь: Синтаксис командной строки 7-Zip. Пример вызова командной оболочки из Java: Выполнение команды оболочки в Java. Вам придется вызвать 7-Zip дважды: один раз, чтобы извлечь Tar из файла .tar.gz или .tgz, и еще раз, чтобы извлечь отдельные файлы из Tar.

Или вы можете просто сделать простую вещь и написать краткий сценарий оболочки или пакетный файл для выполнения распаковки. Нет смысла забивать квадратный колышек в круглое отверстие — для этого и созданы пакетные файлы. В качестве бонуса вы также можете передать им параметры, значительно уменьшив сложность выполнения командной строки java, в то же время позволяя java управлять выполнением.

person BobMcGee    schedule 23.05.2009

Ты пытался

gunzip *.gz
person Peter Lawrey    schedule 23.05.2009

Файлы .gz (сжатые gz) могут хранить имя сжатого файла. Так, например, FuBar.doc можно сохранить внутри myDocument.gz, и при соответствующей распаковке файл может быть восстановлен до имени файла FuBar.doc. К сожалению, java.util.zip.GZIPInputStream не поддерживает какой-либо способ чтения имени файла, даже если оно хранится внутри архива.

person Garnet Ulrich    schedule 24.04.2010