4

transferToこの方法で一見 1000 MB/秒以上の速度でファイルをコピーできる方法を説明してください。372MB のバイナリ ファイルを使用していくつかのテストを実行しましたが、最初のコピーは低速ですが、出力名を変更して再度実行すると、出力ディレクトリに追加のファイルがわずか 180 ミリ秒で表示され、結果として 2000 MB/ を超えます。秒 何が起きてる?私はWindows 7を実行しています。

private static void doCopyNIO(String inFile, String outFile) {
    FileInputStream     fis = null;
    FileOutputStream    fos = null;
    FileChannel         cis = null;
    FileChannel         cos = null;

    long                len = 0, pos = 0;

    try {
        fis = new FileInputStream(inFile);
        cis = fis.getChannel();
        fos = new FileOutputStream(outFile);
        cos = fos.getChannel();
        len = cis.size();
        while (pos < len) {
            pos += cis.transferTo(pos, (1024 * 1024 * 10), cos);    // 10M
        }
        fos.flush();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (cos != null) { try { cos.close(); } catch (Exception e) { } }
        if (fos != null) { try { fos.close(); } catch (Exception e) { } }
        if (cis != null) { try { cis.close(); } catch (Exception e) { } }
        if (fis != null) { try { fis.close(); } catch (Exception e) { } }
    }
}
4

3 に答える 3

2

ファイルが一度読み取られると、OSはそれをキャッシュして、後続の読み取りを高速化すると推測しています。さらに、Wikipedia で説明されているように、Single Instance Storage と呼ばれる NTFS の機能も役割を果たす可能性があります。

異なるが類似したファイルを持つ複数のディレクトリがある場合、これらのファイルの一部は同一の内容を持つ場合があります。単一インスタンス ストレージでは、同一のファイルを 1 つのファイルにマージし、そのマージされたファイルへの参照を作成できます。

https://en.wikipedia.org/wiki/NTFS#Single_Instance_Storage_.28SIS.29

これがあなたが見ているものかどうかはよくわかりませんが、私が考えることができる唯一のことは理にかなっています.

于 2013-09-04T20:09:55.640 に答える
1

これは、バッファリングされた IO パフォーマンスの点でほぼ正しいように見えます....何が起こっているのかというと、ファイルをメモリに対してのみ読み書きしていて、バックグラウンドで、OS が出力ファイルをディスクに「フラッシュ」しているということです。ファイルをディスクに書き込むのにかかる時間を測定するのではなく、メモリに書き込むだけです。

DSYNC OpenOption で新しい Java7 Files.newOutputStream(...)を使用して FileOutputStreams を開くときに、DSYNC オプションを設定して (教育目的で) 再試行することをお勧めします。

このようにして、出力ストリームに書き込むと同時にファイルがディスクに書き込まれます。出力ファイルのメモリ内キャッシュはありません。

于 2013-09-04T20:22:51.473 に答える