5

このコードを使用してTCPソケットを介してファイルを受信するメソッドがあります。

FileOutputStream fileStream = new FileOutputStream(filename.getName());
while (totalRead < size) {
    if (size - totalRead > CHUNKSIZE) {
        read = getInputStream().read(buffer, 0, CHUNKSIZE);
    } else {
        read = getInputStream().read(buffer, 0, size - totalRead);
    }
    totalRead += read;
    fileStream.write(buffer, 0, read);
    fileStream.flush();

    if (System.currentTimeMillis() > nextPrint) {
        nextPrint += 1000;
        int speed = (int) (totalRead / (System.currentTimeMillis() - startTime));
        double procent = ((double)totalRead / size) * 100;
        gui.setStatus("Reciving: " + filename + " at " + speed + " kb/s, " + procent + "% complete");
    }
}
gui.setStatus("Reciving: " + filename + " complete.");
fileStream.close();

FileOutputStream.closeは、大きなファイルを受信するときに非常に長い時間がかかりますが、それはなぜですか?ご覧のとおり、受信したチャンクごとにストリームをフラッシュしています。

4

2 に答える 2

3

OS によってはflush()、データを強制的に OS に書き込む以外に何もしません。FileOutputStream の場合、write() はすべてのデータを OS に渡すため、flush() は何もしません。close()ファイルが実際にディスクに書き込まれることを確認できる場所(または OS によってはそうでない場合)。データの書き込み時にディスクがまだビジーかどうかを確認できます。

500 MB のファイルに 30 秒かかるということは、17 MB/秒で書き込んでいることを意味します。これは、ディスクが非常に遅いか、ファイルがネットワーク共有/ドライブにあるように聞こえます。


これを試すことができます

File file = File.createTempFile("deleteme", "dat"); // put your file here.
FileOutputStream fos = new FileOutputStream(file);
long start = System.nanoTime();
byte[] bytes = new byte[32 * 1024];
for (long l = 0; l < 500 * 1000 * 1000; l += bytes.length)
    fos.write(bytes);
long mid = System.nanoTime();
System.out.printf("Took %.3f seconds to write %,d bytes%n", (mid - start) / 1e9, file.length());
fos.close();
long end = System.nanoTime();
System.out.printf("Took %.3f seconds to close%n", (end - mid) / 1e9);

版画

Took 0.116 seconds to write 500,006,912 bytes
Took 0.002 seconds to close

この速度から、このシステムでは終了時にもデータが書き込まれないことがわかります。つまり、ドライブはそれほど高速ではありません。

于 2011-10-21T13:17:11.513 に答える
1

ファイルストリームを使用しても同じことがわかりました。私が見つけたのは、ファイルを読み取り書き込みとして開いた場合、すべてをキャッシュし、閉じるか破棄するまで書き込みませんでした。フラッシュは書きませんでした。ただし、書き込みによってファイルのサイズが大きくなると、自動フラッシュされます。

書き込みごとに autoflushed として開く。

于 2011-12-30T22:55:05.443 に答える