特别是对于大文件的访问,不必太大,只要到几十K,记事本就吃不消了,也即普通的打开文件方式若不加以优化此时性能会很难接受.但采用内存映射文件做这点就小CASE了.下面是一个例子
HANDLE hFile=CreateFile ("E://DATA.TXT",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);
if (hFile==INVALID_HANDLE_VALUE)
{
printf ("failed to open file!/n");
return ;
}
HANDLE hFileMapping=CreateFileMapping (hFile,NULL,PAGE_READWRITE,0,0,NULL);
DWORD dwFileSizeHigh;
__int64 qwFileSize=GetFileSize (hFile,&dwFileSizeHigh);
CloseHandle (hFile);
qwFileSize+=(((__int64)dwFileSizeHigh)<<32);
printf ("file length:%d/n",qwFileSize);
PBYTE pbBuf,pbTest;
__int64 qwFileOffSet=0; //存储缓存中的指针偏移量
printf ("value of file:/n");
SYSTEM_INFO sinf;
GetSystemInfo (&sinf);
DWORD dwStep=sinf.dwAllocationGranularity;//得到系统的粒度大小,32机是65536
if (qwFileSize<dwStep)
dwStep=(DWORD)qwFileSize;
while (qwFileSize>0)
{
//可对同一个文件作多个数据视图,且具有相关性
pbBuf=(PBYTE)MapViewOfFile (hFileMapping,FILE_MAP_READ,(DWORD)(qwFileOffSet>>32),
(DWORD)(qwFileOffSet&0XFFFFFFFF),dwStep);
pbTest=(PBYTE)MapViewOfFile (hFileMapping,FILE_MAP_WRITE,(DWORD)(qwFileOffSet>>32),
(DWORD)(qwFileOffSet&0XFFFFFFFF),3);
pbTest[0]='a';
printf ("%s",pbBuf);
qwFileOffSet+=dwStep;
qwFileSize-=dwStep;
UnmapViewOfFile (pbBuf);
UnmapViewOfFile (pbTest);
}
上面的程序运行会将文件每隔系统粒度大小修改字符为'a',开始时程序曾出现错误,这里要注意的是:
1.数据视图的权限继承于文件打开时的权限.假如文件打开时只有read权限,即使在创建视图也即CreateFileMapping时使用write权限,在试图修改时也会出错.比如语句pbTest[0]='a';就会出错.
2.同一个文件的多个视图系统自动维护其一致性,因为其对应的内存地址是唯一的.所以修改了pbTest[0],pbBuf[0]的内容也会相应变化.
3.通过GetSystemInfo可以得到系统的内存粒度大小.但假如文件本身小于此粒度,访问则会出错.但事实上若文件不是64KB的整数倍,最后一次调用MapViewOfFile时的映射也会访问文件越界但却没有问题,这一点可以算是MapViewOfFile的一个特性吧,至少对程序员是方便的,不必判断是否是最后一次映射,然后再计算剩余大小.