您的位置:首页 > 其它

内存映射文件学习笔记

2008-01-28 02:02 417 查看
作为访问文件的一种方式,内存映射文件的确使用相当方便.只需在正常的CreateFile完成后通过CreateFileMapping映射到内存,之后就可以像访问内存那样的使用文件了.而且此时文件的缓存是由系统自动调节的,性能和安全性都要提高很多.
特别是对于大文件的访问,不必太大,只要到几十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的一个特性吧,至少对程序员是方便的,不必判断是否是最后一次映射,然后再计算剩余大小.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐