6

パス A からパス B にファイルをコピーし、Windows ファイル システムのキャッシュを抑制する方法を知っている人はいますか?
一般的な用途は、USB ドライブまたはサーバーから大きなファイルをローカル マシンにコピーすることです。ファイルが非常に大きい場合、たとえば 2GiB の場合、Windows はすべてをスワップアウトするようです。C# の例を優先しますが、可能であれば、これは何らかの Win32 呼び出しになると思います。

4

6 に答える 6

6

C#では、このようなものが機能することがわかりました。これを変更して、宛先ファイルに直接コピーできます。

    public static byte[] ReadAllBytesUnbuffered(string filePath)
    {
        const FileOptions FileFlagNoBuffering = (FileOptions)0x20000000;
        var fileInfo = new FileInfo(filePath);
        long fileLength = fileInfo.Length;
        int bufferSize = (int)Math.Min(fileLength, int.MaxValue / 2);
        bufferSize += ((bufferSize + 1023) & ~1023) - bufferSize;
        using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.None,
                                           bufferSize, FileFlagNoBuffering | FileOptions.SequentialScan))
        {
            long length = stream.Length;
            if (length > 0x7fffffffL)
            {
                throw new IOException("File too long over 2GB");
            }
            int offset = 0;
            int count = (int)length;
            var buffer = new byte[count];
            while (count > 0)
            {
                int bytesRead = stream.Read(buffer, offset, count);
                if (bytesRead == 0)
                {
                    throw new EndOfStreamException("Read beyond end of file EOF");
                }
                offset += bytesRead;
                count -= bytesRead;
            }
            return buffer;
        }
    }
于 2011-06-01T09:20:19.820 に答える
5

さらに重要なのは、FILE_FLAG_WRITE_THROUGH と FILE_FLAG_NO_BUFFERING があることです。

MSDN には、両方に関するすばらしい記事があります: http://support.microsoft.com/kb/99794

于 2008-09-07T19:09:32.033 に答える
4

これが役立つかどうかはわかりませんが、FILE_FLAG_SEQUENTIAL_SCAN を使用したパフォーマンスの向上をご覧ください。

まとめ

CreateFile() には FILE_FLAG_SEQUENTIAL_SCAN と呼ばれるフラグがあり、キャッシュ マネージャーがファイルにシーケンシャルにアクセスするように指示します。

シーケンシャル アクセスで潜在的に大きなファイルを読み取る場合は、このフラグを指定してパフォーマンスを向上させることができます。このフラグは、「ほぼ」シーケンシャルなファイルを読み取る場合に役立ちますが、小さな範囲のバイトをスキップする場合があります。

于 2008-09-07T19:02:08.510 に答える
3

ツールの使用を気にしない場合は、ESEUTIL がうまく機能しました。

このブログエントリで、Buffered IO 関数と NonBuffered IO 関数を比較し、ESEUTIL の入手先を確認できます。

technet ブログからいくつかのテキストをコピーします。

上記のバッファリングされた I/O の定義を見ると、認識されているパフォーマンスの問題がどこにあるのか、つまりファイル システムのキャッシュ オーバーヘッドにあることがわかります。コピーの完了後にソース ファイルにアクセスする予定がない場合に、大きなファイルをある場所から別の場所にコピーしようとする場合は、バッファなし I/O (または未加工のファイル コピー) をお勧めします。これにより、ファイル システム キャッシュのオーバーヘッドが回避され、ファイル システム キャッシュが大きなファイル データによって効果的にフラッシュされるのを防ぐことができます。多くのアプリケーションは、CreateFile() を呼び出して空の宛先ファイルを作成し、次に ReadFile() および WriteFile() 関数を使用してデータを転送することでこれを実現します。CreateFile() - CreateFile 関数は、ファイル、ファイル ストリーム、ディレクトリ、物理ディスク、ボリューム、コンソール バッファ、テープ ドライブ、通信リソース、メールスロット、または名前付きパイプを作成または開きます。この関数は、オブジェクトへのアクセスに使用できるハンドルを返します。ReadFile() - ReadFile 関数は、ファイルからデータを読み取り、ファイル ポインターが示す位置から開始します。この関数は、同期操作と非同期操作の両方に使用できます。WriteFile() - WriteFile 関数は、ファイル ポインターで指定された位置にあるファイルにデータを書き込みます。この関数は、同期操作と非同期操作の両方に対応するように設計されています。ネットワーク上で非常に大きなファイルをコピーする場合、私が選んだコピー ユーティリティは、Exchange で提供されるデータベース ユーティリティの 1 つである ESEUTIL です。WriteFile() - WriteFile 関数は、ファイル ポインターで指定された位置にあるファイルにデータを書き込みます。この関数は、同期操作と非同期操作の両方に対応するように設計されています。ネットワーク上で非常に大きなファイルをコピーする場合、私が選んだコピー ユーティリティは、Exchange で提供されるデータベース ユーティリティの 1 つである ESEUTIL です。WriteFile() - WriteFile 関数は、ファイル ポインターで指定された位置にあるファイルにデータを書き込みます。この関数は、同期操作と非同期操作の両方に対応するように設計されています。ネットワーク上で非常に大きなファイルをコピーする場合、私が選んだコピー ユーティリティは、Exchange で提供されるデータベース ユーティリティの 1 つである ESEUTIL です。

于 2008-09-07T19:29:34.013 に答える
0

Eseutil が正解です。また、Win7/2008 R2 以降では、Xcopy で /j スイッチを使用できますが、これは同じ効果があります。

于 2012-12-01T17:30:04.423 に答える