2016-04-10 3 views
0

サイズが約1 GBの大きなファイルを解凍しようとしていますが、ファイル出力ストリームメソッドを使用できません。私の最終的なドキュメントでは、新しいファイルを作成するために圧縮解除されたファイルのバイト配列が必要です。今のところ私は手作業で配列サイズを増やしています。しかし、これは大きなファイルでは遅すぎます。この方法で効率を上げる方法はありますか?System.arrayCopy()メソッドではなくjavaでバイト配列を連結する方法

 if (primaryDocumentInputStream != null) { 
    byte[] tempbuffer = new byte[536870912]; 
    byte[] mainbuffer = new byte[536870912]; 
    int lenMainBuffer = 0; 
    try { 
    int aIntBuffer = aGZIPInputStream.read(tempbuffer); 
    while (aIntBuffer > 0) { 
     byte[] copyBuffer = new byte[lenMainBuffer + aIntBuffer]; 
     System.arraycopy(mainbuffer, 0, copyBuffer, 0, lenMainBuffer); 
     System.arraycopy(tempbuffer, 0, copyBuffer, lenMainBuffer, aIntBuffer); 
     mainbuffer = copyBuffer; 
     aIntBuffer = aGZIPInputStream.read(tempbuffer); 
     lenMainBuffer = mainbuffer.length; 
    } 
    primaryDocumentOutputDocument.setBody(mainbuffer); 
    wfc.putPrimaryDocument(primaryDocumentOutputDocument); 

    } 
+0

バッファのリストを保持し、最後に割り当て/コピーを1つだけ行うことができます。または、より大きな初期バッファを使用することもできます(おそらく既知の拡張サイズを使用します)。しかし、最終的には、単一のビッグバイト配列が予期されるメソッドは再設計が必要です。 – eckes

答えて

3

ByteArrayOutputStreamにデータを書き込みます。バイト配列をラップし、必要に応じてサイズを変更します。終了すると、toByteArrayを呼び出すとバイトが返されます。

ByteArrayOutputStreamとここで書いたことの違いの1つは、バッキングアレイのサイズの2倍の典型的な実装は、nバイトの書き込みにO(n)時間分の複雑さがあることを意味します。ここのような固定された増分で配列を拡大すると、O(n^2)時間の複雑さが得られます。

+0

何よりも効率的ですが、同じことをやっていますが、自分で書くコードを使っていますか?いいえ、あなたが間違いを犯して、悪いことを書いてしまうのでなければ、効率的です。 – Joni

+0

私のコードが質問の中でやっていることよりも効率的です。ご協力ありがとうございました。 私はコードをこのように更新されますが、私はこのエラーを取得する:スレッド内 例外「メイン」java.lang.OutOfMemoryErrorを:Javaヒープスペース ByteArrayOutputStreamデータが=新しいByteArrayOutputStream(); try { int aIntBuffer = gZIPInputStream.read(buffer); (aIntBuffer> 0) { \t data.write(buffer); } –

+0

これは、JVMにすべての圧縮解除されたデータを格納するのに十分なメモリがないことを意味します。ファイルに1GBのデータがある場合は、ヒープサイズを少なくとも3または4GBに増やす必要があります。以前のコメントは、その後コメントを削除した他の人への返答でした。 – Joni

関連する問題