#include<Windows.h>
#include<string>
#include<iostream>
using namespace std;
void main()
{
HANDLE hFile=CreateFile("d://r.txt",GENERIC_WRITE|GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);//打開文件
DWORD dwFileSize=GetFileSize(hFile,NULL);//獲得文件大小
HANDLE hFileMap=CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,dwFileSize+sizeof(char),NULL);//創建一個文件內核對象
PVOID pvFile=MapViewOfFile(hFileMap,FILE_MAP_WRITE,0,0,0);//爲文件的數據預定一塊地址空間區域並將文件的數據作爲物理存儲器調撥給區域
PSTR pch=(PSTR)pvFile;//這個指針包含了文件的所有內容,就好像所有文件內容都放入內存一樣
pch[dwFileSize/sizeof(char)]=0;//由於文件結尾不是‘0’,所以加上,便於進行字符串操作
cout<<pch<<endl;
_strrev(pch);//利用函數對字符串進行翻轉
cout<<pch<<endl;
UnmapViewOfFile(pvFile);//從進程空間撤銷對文件數據的關聯
CloseHandle(hFileMap);
SetFilePointer(hFile,dwFileSize,NULL,FILE_BEGIN);
SetEndOfFile(hFile);
CloseHandle(hFile);
}
3、通過多次內存映射文件來處理大文件
#include<Windows.h>
#include<string>
#include<iostream>
using namespace std;
void main()
{
SYSTEM_INFO sinf;
GetSystemInfo(&sinf);
HANDLE hFile=CreateFile(TEXT("d://huge.txt"),GENERIC_WRITE|GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);//打開文件
DWORD dwFileSizeHigh;
_int64 qwFileSize=GetFileSize(hFile,&dwFileSizeHigh);//獲得文件大小
qwFileSize+=(((_int64)dwFileSizeHigh)<<32);//將高32位加到文件低32位上
HANDLE hFileMap=CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,0,NULL);//創建一個文件內核對象,大小默認爲文件大小
CloseHandle(hFile);
_int64 qwFileOffset=0;//每次映射文件大小,初始值爲0
while(qwFileSize>0){
DWORD dwBytesInBlock=sinf.dwAllocationGranularity;//預定空間的分配麗都
if(qwFileSize<sinf.dwAllocationGranularity)
dwBytesInBlock=(DWORD)qwFileSize;
PCHAR pbFile=(PCHAR)MapViewOfFile(hFileMap,
FILE_MAP_WRITE,
(DWORD)(qwFileOffset>>32),//高32位
(DWORD)(qwFileOffset&0xFFFFFFFF),//低32位
dwBytesInBlock);//爲文件的數據預定一塊地址空間區域並將文件的數據作爲物理存儲器調撥給區域
cout<<"content: "<<pbFile<<endl;
UnmapViewOfFile(pbFile);//從進程空間撤銷對文件數據的關聯
qwFileOffset+=dwBytesInBlock;
qwFileSize-=dwBytesInBlock;
}
CloseHandle(hFileMap);
}
4、內存映射文件和一致性
系統運行我們把同一個文件中的數據映射到多個視圖中,但是數據也仍然是一致的,這是因爲數據文件中的每個頁面在內存中只有一份,但這些內存頁面會被映射到多個進程的地址空間中。
5、以頁交換文件爲後備存儲器的內存映射文件
系統創建以頁交換文件爲後備存儲器的內存映射文件,就不必創建或打開一個專門的磁盤文件,因此不需要調用CreateFile。我們只需要像原來那樣調用CreateFileMapping,並將INVALID_HANDLE_VALUE,作爲hFile參數傳入,這告訴系統創建的文件映射對象的物理存儲器不是磁盤上的文件而是希望系統從頁交換文件中調撥物理存儲器。一旦創建了文件映射對象,並把一個視圖映射到了進程的地址空間中,我們就可以像使用任何內存區域一樣使用它。如果想要和其他進程共享數據,那麼可以再調用CreateFileMapping的時候將一個以0爲終止符的字符串作爲pszName參數傳入。這樣其他想要訪問共享數據的進程就能夠以同一個名稱爲參數來調用CreateFileMapping,或OpenFileMapping,該區域可在進程間共享。
#include<Windows.h>
#include<iostream>
using namespace std;
void main()
{
HANDLE hFileMap=CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,4*1024,TEXT("share"));
PVOID pView=MapViewOfFile(hFileMap,FILE_MAP_READ|FILE_MAP_WRITE,0,0,0);
memcpy(pView,"nihao",6);
cout<<(char *)pView<<endl;
UnmapViewOfFile(hFileMap);
HANDLE hFileOpen=OpenFileMapping(FILE_MAP_READ|FILE_MAP_WRITE,FALSE,TEXT("share"));
PVOID pViewOpen=MapViewOfFile(hFileOpen,FILE_MAP_READ|FILE_MAP_WRITE,0,0,0);
cout<<(char *)pViewOpen<<endl;
UnmapViewOfFile(pViewOpen);
CloseHandle(hFileOpen);
}
6、稀疏調撥的內存映射文件