ファイル上のファイルマッピングオブジェクトの例(C++)

説明:

下記サンプルでは、ファイルに保存されているツリー構造のデータを管理する。サンプルが起動されるたびに、ツリーにノードを追加する。ノードクラスのnew演算子において、ファイルマッピングオブジェクトのビュー上にノードのメモリ領域を確保することにより、ファイル上のデータであることを意識せずに、データを操作することができる。

キーワード:

サンプルコード:

#define STRICT

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

const char *MAPPED_FILE_NAME = "Test File Mapping Object";
const char *MUTEX_NAME = "Test Mutex Object";

const int CHILD_MAX = 20;

typedef struct {
	int NodeNum;
	int HeapSize;
	BYTE Heap[1];
} MAPPED_FILE_DATA;

MAPPED_FILE_DATA *pView;

class Node {
public:
	int NodeNo;
	int ChildNum;
	Node *Childs[CHILD_MAX];
	
	void AddChild(Node *child);
	void DispTree(bool bros, char *prefix);
	void *operator new(size_t size);
	Node();
};

void *Node::operator new(size_t size)
{
	void *p;

	p = &pView->Heap[pView->HeapSize];
	pView->HeapSize += size;

	return p;
}

Node::Node()
{
	ChildNum = 0;
	NodeNo = pView->NodeNum++;
}

void Node::AddChild(Node *child)
{
	Childs[ChildNum++] = child;
}

void Node::DispTree(bool bros, char *prefix)
{
	char child_prefix[1000];
	int i;

	printf("%s|\n%s+--%02d\n", prefix, prefix, NodeNo);
	if(!bros) sprintf(child_prefix, "%s    ", prefix);
	else sprintf(child_prefix, "%s|   ", prefix);

	for(i=0; i<ChildNum; i++) {

		Childs[i]->DispTree((i < ChildNum-1), child_prefix);
	}
}

int main()
{
	Node *RootNode;
	Node *NewNode;
	Node *CurrentNode;

	HANDLE hFile;
	HANDLE hMap;
	BOOL bAlreadyExisting;

	hFile = CreateFile("nodes.dat", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL);
	bAlreadyExisting = (GetLastError() == ERROR_ALREADY_EXISTS);
	hMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, sizeof(MAPPED_FILE_DATA), "test file mapping object");
	pView = (MAPPED_FILE_DATA *)MapViewOfFileEx(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0, (void *)0x00900000);
	CloseHandle(hFile);

	if(!bAlreadyExisting) {
		pView->NodeNum = 0;	
		pView->HeapSize = 0;
		RootNode = new Node;
	} else {
		RootNode = (Node *)&pView->Heap[0];
	}

	srand(time(NULL));

	CurrentNode = RootNode;
	while(CurrentNode->ChildNum>0) {
		if((rand() % 10) <2) break;
		CurrentNode = CurrentNode->Childs[rand() % CurrentNode->ChildNum];
	}
	
	NewNode = new Node;
	CurrentNode->AddChild(NewNode);

	RootNode->DispTree(false, "");

	UnmapViewOfFile(pView);
	CloseHandle(hMap);

	return 0;
}

メモ:
以下は実行例。実行するたびに、ノードが増えていく。

|
+--00
    |
    +--01
        |
        +--02
        |   |
        |   +--03
        |   |   |
        |   |   +--04
        |   |
        |   +--05
        |   |
        |   +--06
        |   |   |
        |   |   +--09
        |   |   |
        |   |   +--10
        |   |   |
        |   |   +--11
        |   |
        |   +--07
        |   |   |
        |   |   +--12
        |   |       |
        |   |       +--13
        |   |       |
        |   |       +--14
        |   |       |
        |   |       +--15
        |   |
        |   +--08
        |   |   |
        |   |   +--18
        |   |
        |   +--17
        |
        +--16

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

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