2

バイナリ比較機能を作成するために、CreateFileW 関数を使用して 2 つのファイルのバイナリ コンテンツを読み込もうとしています。ただし、これによりファイル全体がメモリにバッファリングされ、大きな (500MB) ファイルでは問題になります。

代わりにファイルの一部をバッファリングできる他の関数を探しましたが、これらの関数でバッファがどのように機能するかを具体的に説明しているドキュメントは見つかりませんでした (私はこれに少し慣れていないので、多分私は明らかなことを見逃しています)。

これまでのところ、私が見つけたと思われる最良の一致は ReadFile です。定義可能なバッファーがあるようですが、CreateFileW のように、別のバッファーが舞台裏で実装されないかどうかは完全にはわかりません。

使用するのに適した機能について何か意見はありますか?

4

4 に答える 4

7

これを行うには、メモリ マップ ファイルを使用できます。で開き、 thenをcreateFile使用してデータへのポインタを取得します。createFileMappingMapViewOfFile

于 2009-08-19T18:56:10.040 に答える
5

CreateFile()を呼び出しても、それ自体はターゲットファイルの内容をバッファリングしたり読み取ったりしません。CreateFile()を呼び出した後、ReadFile()を呼び出して、ファイルの最初のキロバイトを読み取るなど、ファイルの必要な部分を取得する必要があります。

DWORD cbRead;
BYTE buffer[1024];
HANDLE hFile = ::CreateFile(filename,
                            GENERIC_READ,
                            FILE_SHARE_READ,
                            NULL,
                            OPEN_EXISTING,
                            FILE_ATTRIBUTE_NORMAL,
                            NULL);
::ReadFile(hFile, sizeof(buffer), &cbRead, NULL);
::CloseHandle(hFile);

さらに、ファイルのランダムな部分を読み取りたい場合は、 ReadFile()を呼び出す前にSetFilePointer()を使用できます。たとえば、1メガバイトから始まる1キロバイトをファイルに読み取ります。

DWORD cbRead;
BYTE buffer[1024];
HANDLE hFile = ::CreateFile(filename,
                            GENERIC_READ,
                            FILE_SHARE_READ,
                            NULL,
                            OPEN_EXISTING,
                            FILE_ATTRIBUTE_NORMAL,
                            NULL);
::SetFilePointer(hFile, 1024 * 1024, NULL, FILE_BEGIN);
::ReadFile(hFile, sizeof(buffer), &cbRead, NULL);
::CloseHandle(hFile);

もちろん、ファイルが開いている間は、SetFilePointer()とReadFile()を何度でも呼び出すことができます。ReadFile()を呼び出すと、ReadFile()によって読み取られた最後のバイトの直後のバイトにファイルポインタが暗黙的に設定されます。

さらに、使用するファイル管理関数のドキュメントを読み、戻り値を適切にチェックして、発生する可能性のあるエラーをトラップする必要があります。

Windowsは、その裁量により、使用可能なシステムメモリを使用して開いているファイルの内容をキャッシュできますが、実行中のプログラムでメモリが必要な場合、このプロセスによってキャッシュされたデータは破棄されます(結局、キャッシュされたデータは再読み取りできます)。必要に応じてディスクから)。

于 2009-08-19T19:20:09.400 に答える
5

CreateFile バッファリングの意味がわからない - CreateFile はファイルの内容全体を読み取るわけではなく、ReadFile を呼び出す前に CreateFile を呼び出す必要があります。

ReadFile はあなたが望むことをします - OS は日和見的にデータをキャッシュするためにデータの前にいくつかの読み取りを行うかもしれませんが、500 MB のファイル全体を読み取るわけではありません。

本当にバッファリングが必要ない場合は、FILE_FLAG_NO_BUFFERING を CreateFile に渡し、ファイル アクセスがボリューム セクタ サイズの倍数になるようにします。これを行わないことを強くお勧めします。システム ファイル キャッシュは何らかの理由で存在し、パフォーマンスに役立ちます。ファイルをメモリにキャッシュしても、システム全体のメモリ使用量に影響はありません。メモリが圧迫されると、システム ファイル キャッシュが縮小します。

他の人が述べたように、メモリマップファイルも使用できます。メモリ マップド ファイルと ReadFile の違いは、主にインターフェイスだけです。最終的には、ファイル マネージャーが、バッファリングを含め、同様の方法で要求を満たします。インターフェイスはもう少し直感的に見えますが、エラーが発生すると例外が発生し、キャッチする必要があることに注意してください。そうしないと、プログラムがクラッシュします。

于 2009-08-19T19:08:38.563 に答える
1

MapViewOfFileが必要だと思います。

于 2009-08-19T18:58:02.737 に答える