2015-02-17 4 views
0

мой вопрос может быть не полностью связан с Java, но в настоящее время я ищу метод для объединения нескольких сжатых (gzipped) текстовых файлов без необходимости их повторного сжимания вручную. Допустим, у меня есть 4 файла, весь текст, сжатый с помощью gzip, и вы хотите сжать их в один файл * .gz без декомпозиции +. Мой текущий метод, чтобы открыть InputStream и разобрать файл построчно, хранение в GZIPoutputstream, который работает, но не очень быстро .... Я мог бы, конечно, также называютСочетание сжатых текстовых файлов Gzipped с использованием Java

zcat file1 file2 file3 | gzip -c > output_all_four.gz 

Это будет работать, но слишком тоже не очень быстро.

Моей идеей было бы скопировать входной поток и записать его в выходной поток непосредственно без «разбора» потока, поскольку мне вообще не нужно что-либо манипулировать. Что-то вроде этого возможно?

+0

Что об использовании 'кота file1 file2 file3> output_all_three.gz'? – SubOptimal

+0

В теории: Да. Практически многие инструменты затем воспринимают вывод как отдельные файлы, то есть они не работают на выходе таким образом. – w3b1x

+0

Какой 'много инструментов' вы имеете в виду? 'gzip' не обманывается, Java не обманывается. И использование 'gzip' таким образом является допустимым примером http://www.gnu.org/software/gzip/manual/html_node/Advanced-usage.html. – SubOptimal

ответ

2

Найдите ниже простого решения на Java (оно аналогично моему примеру cat ...). Любые буферизации ввода/вывода были опущены, чтобы сохранить код тонким.

public class ConcatFiles { 

    public static void main(String[] args) throws IOException { 
     // concatenate the single gzip files to one gzip file 
     try (InputStream isOne = new FileInputStream("file1.gz"); 
       InputStream isTwo = new FileInputStream("file2.gz"); 
       InputStream isThree = new FileInputStream("file3.gz"); 
       SequenceInputStream sis = new SequenceInputStream(new SequenceInputStream(isOne, isTwo), isThree); 
       OutputStream bos = new FileOutputStream("output_all_three.gz")) { 
      byte[] buffer = new byte[8192]; 
      int intsRead; 
      while ((intsRead = sis.read(buffer)) != -1) { 
       bos.write(buffer, 0, intsRead); 
      } 
      bos.flush(); 
     } 

     // ungezip the single gzip file, the output contains the 
     // concatenated input of the single uncompressed files 
     try (GZIPInputStream gzipis = new GZIPInputStream(new FileInputStream("output_all_three.gz")); 
       OutputStream bos = new FileOutputStream("output_all_three")) { 
      byte[] buffer = new byte[8192]; 
      int intsRead; 
      while ((intsRead = gzipis.read(buffer)) != -1) { 
       bos.write(buffer, 0, intsRead); 
      } 
      bos.flush(); 
     } 
    } 
} 
+0

Я дам это попробовать, смогу работать :) – w3b1x

1

Вышеупомянутый метод работает, если вам просто требуется gzip для многих ZIP-файлов. В моем случае я сделал веб-сервлет, и мой ответ был в 20-30 КБ. Поэтому я отправлял отложенный ответ.

Я попытался заархивировать все мои отдельные файлы JS только на сервере, а затем добавить динамическое время выполнения кода с использованием вышеуказанного метода. Я мог напечатать весь ответ в моем файле журнала, но хром смог распаковать только первый файл. Выход останова поступал в байтах.

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

https://bugs.chromium.org/p/chromium/issues/detail?id=20884