程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> 內存映射文件學習筆記

內存映射文件學習筆記

編輯:.NET實例教程
作為訪問文件的一種方式,內存映射文件的確使用相當方便.只需在正常的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時的映射也會訪問文件越界但卻沒有問題,

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved