版權(quán)聲明:轉(zhuǎn)載時(shí)請(qǐng)以超鏈接形式標(biāo)明文章原始出處和作者信息及本聲明
http://feizf.blogbus.com/logs/18768267.html
由于某種需要,很多時(shí)候可能需要對(duì)文件進(jìn)行隨機(jī)偏移讀取和修改。一般情況下,可以先f(wàn)seek到文件中制定的位置,再將文件塊讀入內(nèi)存-修改-寫(xiě)回。 對(duì)于大文件(GB量級(jí)),或者頻繁的隨機(jī)文件讀寫(xiě),這樣的方式會(huì)非常耗費(fèi)時(shí)間。
這類(lèi)操作一般是以?xún)?nèi)存映射文件(即將文件映射到進(jìn)程的某一塊空間)的方式來(lái)加以處理的。使用內(nèi)存映射文件處理存儲(chǔ)于磁盤(pán)上的文件時(shí),將不必再對(duì)文件執(zhí)行I/O操作,這意味著在對(duì)文件進(jìn)行處理時(shí)將不必再為文件申請(qǐng)并分配緩存,所有的文件緩存操作均由系統(tǒng)直接管理,由于取消了將文件數(shù)據(jù)加載到內(nèi)存、數(shù)據(jù)從內(nèi)存到文件的回寫(xiě)以及釋放內(nèi)存塊等步驟,所以效率大大提高。
下面試總結(jié)的內(nèi)存文件映射使用方式:
//開(kāi)始
//獲得文件句柄
HANDLE hFile=CreateFile(
"data.dat", //文件名
GENERIC_READ|GENERIC_WRITE, //對(duì)文件進(jìn)行讀寫(xiě)操作
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING, //打開(kāi)已存在文件
FILE_ATTRIBUTE_NORMAL,
0);
//返回值size_high,size_low分別表示文件大小的高32位/低32位
DWORD size_low,size_high;
size_low= GetFileSize(hFile,&size_high);
//創(chuàng)建文件的內(nèi)存映射文件。
HANDLE hMapFile=CreateFileMapping(
hFile,
NULL,
PAGE_READWRITE, //對(duì)映射文件進(jìn)行讀寫(xiě)
size_high,
size_low, //這兩個(gè)參數(shù)共64位,所以支持的最大文件長(zhǎng)度為16EB
NULL);
if(hMapFile==INVALID_HANDLE_VALUE)
{
AfxMessageBox("Can't create file mapping.Error%d:\n", GetLastError());
CloseHandle(hFile);
return;
}
//把文件數(shù)據(jù)映射到進(jìn)程的地址空間
void* pvFile=MapViewOfFile(
hMapFile,
FILE_MAP_READ|FILE_MAP_WRITE,
0,
0,
0);
unsigned char *p=(unsigned char*)pvFile;
//至此,就獲得了外部文件data.dat在內(nèi)存地址空間的映射,
//下面就可以用指針p"折磨"這個(gè)文件了
CString s;
p[size_low-1]=0x1f;
p[size_low-2]=0x2f; //修改該文件的最后兩個(gè)字節(jié)(文件大小<4GB高32位為0)
s.Format("%#x,%#x,%#x",p[size_low-3],p[size_low-2],p[size_low-1]);
//讀文件的最后3個(gè)字節(jié)
AfxMessageBox(s);
//結(jié)束
UnmapViewOfFile(pvFile); //撤銷(xiāo)映射
CloseHandle(hFile); //關(guān)閉文件
與本文相關(guān)的文章還有:
1.[VC++6.0共享內(nèi)存技術(shù)總結(jié)] http://feizf.blogbus.com/logs/17056014.html
2.[Linux下讀寫(xiě)速度測(cè)試]中的linux內(nèi)存映射 http://feizf.blogbus.com/logs/10234312.html
參考文章
1. VC++中使用內(nèi)存映射文件處理大文件
http://www.x5dj.com/blog/00199734/00052571.shtml
2. <<windows核心編程>>
聯(lián)系客服