2016-05-15 12 views
1

私は、複数の接続を使用してhttpでファイルをダウンロードできる基本ダウンロードマネージャを開発しています。ダウンロードの終わりに、ファイルの各部分を含む複数の一時ファイルがあります。Javaでバイナリファイルをマージする最善の方法

これで、それらを1つのファイルにマージします。

出力ストリームを作成してストリームを入力し、入力を適切な順序で出力にパイプするだけでは簡単ではありません。

しかし、私はそれをより効率的に行う方法はあるのでしょうか?私の理解から、ここで何が起きるかは、JVMがバイトごとにバイトを読み込み、バイトごとにバイトを出力するということです。

だから基本的に私が持っている:いくつかのCPUの命令は、おそらく実行され、バイトはおそらくCPUのキャッシュ にコピーされます - - メモリ に店舗バイト - - ディスク からバイトを読み ディスクにバイトを書き込み

ディスクにプロセスを保存する方法があるかどうか疑問に思っていましたか?私は分かりやすいのか分かりませんが、基本的にディスクに "ディスクを入れて、これらのファイルを取り出して、それらのファイルを作成してください"

短い文では、私はCPUを&可能な限り低い。

+2

ここをクリックしてください:https://thomaswabner.wordpress.com/2007/10/09/fast-stream-copy-using-javanio-channels/ –

+0

ファイルを連結することはあまりにもまれであり、一般的な低レベルDOS操作。しかし、上記のリンクは長い道のりです。最適化の1つは、(最も一般的な)ディスクページサイズの倍数のサイズを持つ大きな中間バッファを使用することです。 – usr2564301

+0

@RafaelOsipov:これはかなり良い方法です。 – Tiller

答えて

2

理論上、この操作はファイルシステムレベルで行うことができます。データを移動せずに1つのinodeから別のinodeにブロックリストを追加できます。これはあまり実用的ではありませんが、おそらくオペレーティングシステムをバイパスしてディスクに直接アクセスする必要があります。この方法は、潜在的にはるかに効率的、このチャネルから読み込み、ターゲットチャネルに書き込みを行う単純なループよりも

次善の策はFileChannel.transferTo or transferFromメソッドを使用しても良いです。多くのオペレーティングシステムでは、実際にファイルシステムのコピーを行わずに、バイトをファイルシステムキャッシュからターゲットチャネルに直接転送できます。

また、ストリームやRandomAccessFileを使用して大きなバイトブロックを読み書きすることもテストする必要があります。チャネルを使用するよりも高速である可能性があります。ここにはtesting sequential IO performance in Javaについての良い記事があります。

+1

私は自分自身のテストをいくつか実行しました。私の場合は一番だ。テストケースでは5〜10倍高速です。ありがとうございました。 – Tiller