ファイル上のファイルマッピングオブジェクトの例(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 更新)
本ドキュメントの内容は保証しません。本ドキュメントによって生じた結果について、一切の責任を負いません。