ReadFileScatter ファイルからデータを読み込み、複数のメモリブロックに格納する

Cの宣言:

BOOL ReadFileScatter(
	HANDLE hFile,
	FILE_SEGMENT_ELEMENT SegElements[],
	DWORD ReadSize,
	LPDWORD Reserved,
	LPOVERLAPPED Overlapped);

説明:

hFileで指定したファイルからデータを読み込み、SegElementで指定したバッファ群へ先頭から順に、格納していく。

本関数はNT4.0SP2以降で使用可能。

ファイルの読み込み位置は、Overlapped構造体のOffset及びOffsetHighメンバで指定する。

FILE_SEGMENT_ELEMENTは、64bitポインタである。64bitポインタがサポートされていない環境の場合、上位32bitを0にすること。

SegElementの指すバッファのサイズは、メモリページのサイズと同一であるとみなされる。また、SegElementの指すバッファの位置は、メモリページのサイズの境界に整列されていなければならない。

hFileに指定するファイルは、GENERIC_READ, FILE_FLAG_OVERLAPPED, FILE_FLAG_NO_BUFFERINGを指定してオープンしたものでなければならない。

本関数は、常にオーバーラップ操作によって読み込みが行われる。

引数の意味は以下の通り。
hFile 読み込み元のファイルを指すハンドル。
SegElements 読み込み結果を格納するバッファ群へのポインタの配列。
ReadSize 読み込むバイト数。
Reserved NULLでなければならない。
Overlapped 非同期I/Oの情報。

戻り値は、関数の実行に成功したか否かを表す真偽値である。ただし、読み込みは非同期で行われるため、すべてのデータを読み込む以前でも本関数は終了する。その場合、戻り値はFALSEとなり、その際のエラー値はERROR_IO_PENDINGとなる。

Cのサンプル:

ReadFileScatterを使用することにより、ファイル上のデータを複数のメモリブロックに分割して読み込む。 ただし、この例ではWriteFileGatherのサンプルコードで示したWriteBuffersを用いて作成したファイルから、データを読み込むものとする。
void ReadBuffers()
{
	HANDLE hFile;
	BYTE *BufList[PAGE_NUM];
	FILE_SEGMENT_ELEMENT SegElement[PAGE_NUM + 1];
	SYSTEM_INFO si;
	OVERLAPPED ov;
	BYTE *BaseAddress;
	DWORD i, j;

	/* 読み込み先のバッファの用意 */
	GetSystemInfo(&si);
	BaseAddress  = VirtualAlloc(NULL, si.dwPageSize * PAGE_NUM, MEM_COMMIT, PAGE_READWRITE);

	for(i=0; i<PAGE_NUM; i++) BufList[i] = BaseAddress + si.dwPageSize * i;

	/* ファイルのオープン */
	hFile = CreateFile(
		"test.dat",
		GENERIC_READ | GENERIC_WRITE,
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		NULL,
		OPEN_EXISTING,
		FILE_ATTRIBUTE_ARCHIVE | FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING,
		NULL);

	/* ReadFileScatterへの入力情報の初期化 */
	for(i=0; i<PAGE_NUM; i++) SegElement[i] = (FILE_SEGMENT_ELEMENT)BufList[i];
	SegElement[PAGE_NUM] = (FILE_SEGMENT_ELEMENT)NULL;
	
	ov.Offset = 0;
	ov.OffsetHigh = 0;
	ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

	/* ファイルから読み込み */
	printf("読み込み開始.\n");
	ReadFileScatter(hFile, SegElement, si.dwPageSize * PAGE_NUM, NULL, &ov);

	printf("待機中...\n");
	WaitForSingleObject(ov.hEvent, INFINITE);

	printf("完了.\n");

	/* 読み込んだデータのチェック */
	printf("データのチェック...\n");

	for(i=0; i<PAGE_NUM; i++) for(j=0; j<si.dwPageSize; j++) {
		if(*(BufList[i] + j) != i % 256) {
			printf("不正なデータ発見.\n");
			goto Exit;
		}
	}

	printf("チェック終了.\n");

Exit:
	/* 後処理 */
	CloseHandle(hFile);
	VirtualFree(BaseAddress, 0, MEM_RELEASE);
	CloseHandle(ov.hEvent);

}

(original text:1999/02/12 更新)

本ドキュメントの内容は保証しません。本ドキュメントによって生じた結果について、一切の責任を負いません。