Javaに関する様々な情報をご紹介します。

Javaに関する様々な情報をご紹介します。
評価

0

高速な解凍方法

 Gzip形式のファイル解凍処理をjavaで作成しています。GZIPInputStreamを用いて、圧縮ファイルから1バイトずつ読み取り、ターゲットディレクトリに書き出すという方法を行っているのですが、圧縮ファイルの容量の関係上(圧縮時で5G程度)、解凍処理をさらに高速化する必要があります。

 現在、GZIPInputStreamでの処理で、3分/1Gほど要しており、最終的には1Gの圧縮ファイルに対して、1分前後で処理を行うことを目指していますが、何か良い方法があれば参考にさせて下さい。宜しくお願いします。

(現在、UNLHA.dll等の外部ツールを用いた処理も検討しています。)

10

回答

7577

閲覧

10件の回答

評価

0

>圧縮ファイルから1バイトずつ読み取り

とりあえず、Buffered Streamを使うことから始めてみては。

評価

0

>Buffered Streamを使うことから始めてみては

現在、圧縮ファイルをGZIPInputStreamに取り込
み、Buffered Streamを使ってファイル書き出しを行っていま
す。想定されるファイル容量やメモリなどを考慮してこのよう
な処理方法を取っているのですが、GZIPInputStream → メ
モリベースの読み/書きですと、安定性はともかく、速度的に
限界があると考えています。

評価

0

なんで、読み取りにBuffered Streamを使わないの?

評価

0

不良社員さん、kjさんご回答ありがとうございます。

>なんで、読み取りにBuffered Streamを使わないの?

処理内容をもう少し詳しく書くべきでした。

正確には、GZIPInputStreamをFileInputStreamで生成し、
それをBufferedInputStreamを使って読み取り、
BufferedOutputStreamで書き出しています。(圧縮ファイル
は通常のファイルとして扱うことが出来ないので、まず
GZIPInputStreamに取り込みます。)
BufferedInputStream →BufferedOutputStreamの処理ソー
スはこのようになっています。

 BufferedInputStream bis
                    = new BufferedInputStream(
                          new GZIPInputStream(
                             new FileInputStream( file ) ) );

               int n = file.getName().length();
               String bodyName = file.getName().substring( 
0, n-3 );

               BufferedOutputStream bos
                    = new BufferedOutputStream(
                          new FileOutputStream(
                             new File( bodyName ) ) );

    int c;
               while( ( c = bis.read() ) != EOF ) {
                  bos.write( (byte)c );
               } 
               bis.close();
               bos.close();
               flag = true;

評価

0

そのソースだと、バッファを使っていない。

read(byte[] b,int off,int len)
write(byte[] b,int off, int len)

を使うようにすればいいと思います。

私自身はやったことないので断言できないけど、速くなると思います。

評価

0

>read(byte[] b,int off,int len)

ご指摘ありがとうございます。
一度に読み取る最大バイト数等のパラメータをこちらで指定で
きるような感じでしょうか(まだAPIをざっと見ただけなの
で、理解が不足しているかもしれません)。read()では1バイ
ト単位でしか読み書きが出来なかったので、こちらのほうがよ
り高速な解凍が行えそうです。

評価

0

>そのソースだと、バッファを使っていない。
BufferedOutputStreamのソース嫁。

byte[]を渡すほうが速いのは確かだけど。

Buffered*Streamのコンストラクタの第二引数にバッファサイズを渡せる。
デフォルトは8kだから、大きくしてやれば多少は違う。

評価

0

>BufferedOutputStreamのソース嫁。

ご指摘ありがとうございます。

さっそく、ソース読んでみます。

とりあえず、お詫びだけしときます。

評価

0

BufferedOutputStreamのソース読みました。

私自身の誤りが理解できてよかったです。

$さん、ありがとうございます。

評価

0

$さん、kjさん、ご指摘ありがとうございます。

最悪の場合、外部解凍ツールにコマンドで処理を渡してしまう
方向性も検討していたのですが、まずはストリームのバッファ
サイズを多く取るという方向性で進めて行きたいと思います。

質問から6ヶ月以上経過しているので、回答を書き込むことはできません。