特別是對於大文件的訪問,不必太大,只要到幾十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時的映射也會訪問文件越界但卻沒有問題,