WriteFileGather 複数のメモリブロックを一度にファイルへ書き込む

Cの宣言:

BOOL WriteFileGather(
	HANDLE hFile,
	FILE_SEGMENT_ELEMENT SegArray[],
	DWORD WriteSize,
	LPDWORD Reserved,
	LPOVERLAPPED Overlapped);

説明:

SegArrayで指定したバッファ群について、各バッファの内容を順にhFileで指定されたファイルへ書き込んでいく。

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

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

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

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

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

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

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

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

Cのサンプル:

WriteFileGatherを使用することにより、複数のメモリブロックを一気にまとめてファイルに書き込む。(この例では、入力データは連続したメモリブロックであるが、WriteFileGatherには不連続のメモリブロックをまとめて書き込む能力がある)
#define PAGE_NUM 4096

void WriteBuffers()
{
	HANDLE hFile;
	BYTE *BufList[PAGE_NUM];
	FILE_SEGMENT_ELEMENT SegElement[PAGE_NUM + 1];
	SYSTEM_INFO si;
	OVERLAPPED ov;
	BYTE *BaseAddress;
	DWORD i;

	/* 書き込むデータの用意 */
	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;
		FillMemory(BufList[i], si.dwPageSize, i % 256);
	}

	/* ファイルの作成 */
	hFile = CreateFile(
		"test.dat",
		GENERIC_READ | GENERIC_WRITE,
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		NULL,
		OPEN_ALWAYS,
		FILE_ATTRIBUTE_ARCHIVE | FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING,
		NULL);

	/* WriteFileGatherへの入力情報の初期化 */
	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");
	WriteFileGather(hFile, SegElement, PAGE_NUM * si.dwPageSize, NULL, &ov);

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

	printf("完了.\n");
	
	/* 後処理 */
	CloseHandle(hFile);
	VirtualFree(BaseAddress, 0, MEM_RELEASE);
	CloseHandle(ov.hEvent);
}

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

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