2

接続を介して大きなファイルを送信しようとしましたSocketが、実行が遅く、転送速度を向上させるためにこのコードを最適化できるかどうか疑問に思っていました.

これは、ファイルを送信するための私のコードです:

byte[] buffer = new byte[65536];
int number;

while ((number = fileInputStream.read(buffer)) != -1) {
    socketOutputStream.write(buffer, 0, number);
}

socketOutputStream.close();
fileInputStream.close();

これは、他のマシンでファイルを受信するために使用するものです。

byte[] buffer = new byte[65536];

InputStream socketStream= clientSocket.getInputStream();
File f=new File("C:\\output.dat");

OutputStream fileStream=new FileOutputStream(f);

while ((number = socketStream.read(buffer)) != -1) {
    fileStream.write(buffer,0,number);
}

fileStream.close();
socketStream.close();

fileStream への書き込みにほとんどの時間がかかっていると思います。このコードを高速化するためのアドバイスを誰でも提供できますか。

4

3 に答える 3

5

ステートメントのfinallyブロックがないことを除けば、そのコードには明らかに問題はありません。close

どのくらいのデータにどのくらい時間がかかりますか?時間がかかっている可能性はほとんどありませんFileOutputStream。ネットワークが低速である可能性がはるかに高くなります。ネットワークからの読み取りとファイルシステムへの書き込みを並行して行う可能性がありますが、それを正しく行うには多くの作業が必要であり、IMOにそれほど大きなメリットがもたらされる可能性はほとんどありませ

于 2012-04-13T19:31:56.570 に答える
1

FileOutputStreamの周りでBufferedOutputStreamを試すことができます。ネットワークから読み取ったカウントに関係なく、すべてのディスク書き込みをブロックアラインする効果があります。大きな違いはないと思いますが、少し役立つかもしれません。

于 2012-04-14T03:16:33.640 に答える
1

大きなファイルをFTPで転送するという同様の問題がありました。ハードドライブからの読み取りとネットワークへの書き込みに同じバッファーを使用することが問題であることに気付きました。ファイル システム IO は、ハード ドライブがすべてのシークと読み取りを行う作業がはるかに少ないため、より大きなバッファーを好みます。一方、ネットワークは、スループットを最適化するために、より小さなバッファーを優先します。

解決策は、大きなバッファを使用してハード ディスクから読み取り、このバッファをネットワーク ストリームに小さなチャンクで書き込むことです。

4 MB の読み取りと 32 KB の書き込みで、任意のファイルの全長に対して 100% の使用率で NIC を最大限に活用することができました。次に、一度に 32kb を読み込んでメモリに保存し、一度に 4mb をハード ドライブに書き込むことで、サーバー上でミラーリング バージョンを実行できます。

于 2013-02-11T07:42:27.437 に答える