說明
圖1:執行正常
圖2:0x20000處的32字節已經給修改
圖3:0x28804處的值讀取正確
效果
源碼
#include
#include
#define BUFFSIZE 1024//內存大小
#define FILE_MAP_START 0x28804//文件映射的起始位置
LPTSTR lpcTheFile = TEXT("misaka.dat");//文件名
int main(int argc, PCHAR argv[]){
HANDLE hMapFile;//文件內存映射句柄
HANDLE hFile;//文件句柄
DWORD dBytesWritten;//寫入的字節數
DWORD dwFileSize;//文件大小
DWORD dwFileMapSize;//文件映射的大小
DWORD dwMapViewSize;//視圖大小
DWORD dwFileMapStart;//文件映射視圖的起始位置
DWORD dwSysGran;//系統內存分配粒度
SYSTEM_INFO SysInfo;//系統信息
LPVOID lpMapAddress;//內存映射區域的起始位置
PCHAR pData;//數據
INT i;//循環變量
INT iData;
INT iViewDelta;
BYTE cMapBuffer[32];//存儲從映射中計出的數據
//創建一個文件
hFile = CreateFile(lpcTheFile, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE){
printf("創建文件失敗: %s\n", GetLastError());
return 1;
}
//依次寫入整數,一共寫入65535個
//在32位平臺下,大小為65535*4字節
for (i = 0; i< 65535; i++){
WriteFile(hFile, &i, sizeof(i), &dBytesWritten, NULL);
}
//查看寫入完成后的文件大小
dwFileSize = GetFileSize(hFile, NULL);
printf("文件大小: %d\n", dwFileSize);
//獲得系統信息,內存分配粒度,目的是為了映射的數據與系統內存分配粒度對齊,提高內存訪問效率
GetSystemInfo(&SysInfo);
dwSysGran = SysInfo.dwAllocationGranularity;
//計算mapping的起始位置
dwFileMapStart = (FILE_MAP_START / dwSysGran) * dwSysGran;
//計算mapping view的大小
dwMapViewSize = (FILE_MAP_START % dwSysGran) + BUFFSIZE;
//計算mapping的大小
dwFileMapSize = FILE_MAP_START + BUFFSIZE;
//計算需要讀取的數據的偏移
iViewDelta = FILE_MAP_START - dwFileMapStart;
//創建file mapping
hMapFile = CreateFileMapping(
hFile,//需要映射的文件的句柄
NULL,//安全選項:默認
PAGE_READWRITE,//可讀可寫
0,//mapping對象的大小 high
dwFileMapSize,//mapping對象的大小 low
NULL//mapping對象的名字
);
if (hMapFile == NULL){
printf("創建文件映射對象失敗: %d\n", GetLastError());
return 1;
}
//映射視圖
lpMapAddress = MapViewOfFile(
hMapFile,//mapping對象的句柄
FILE_MAP_ALL_ACCESS,//可讀可寫
0,//映射文件偏移 high
dwFileMapStart,//映射文件偏移 low
dwMapViewSize//映射到視圖的數據大小
);
if (lpMapAddress == NULL){
printf("映射文件視圖失敗: %d\n", GetLastError());
return 1;
}
printf("文件映射視圖相對于文件的起始偏移位置: 0x%x\n", dwFileMapStart);
printf("文件映射視圖的大小: 0x%x\n", dwMapViewSize);
printf("文件映射對象的大小: 0x%x\n", dwFileMapSize);
printf("從相對于映射視圖 0x%x 字節的位置讀取數據", iViewDelta);
//將指向數據的指針偏移,到達我們關系的地方
pData = (PCHAR)lpMapAddress + iViewDelta;
//讀取數據,賦值給變量
iData = *(PINT)pData;
//顯示讀取的數據
printf("為: 0x%.8x\n", iData);
//從mapping中賦值數據,32字節并打印
CopyMemory(cMapBuffer, lpMapAddress, 32);
printf("lpMapAddress起始的字節是: ");
for (i = 0; i< 32; i++){
printf("0x%.2x ", cMapBuffer[i]);
}
//將mapping的前32字節用0xff填充
FillMemory(lpMapAddress, 32, (BYTE)0xff);
//將映射的數據寫回到硬盤
FlushViewOfFile(lpMapAddress, dwMapViewSize);
printf("\n已將lpMapAddress開始的字節使用0xff填充\n");
//關閉mapping對象
if (!CloseHandle(hMapFile)){
printf("關閉映射對象失敗: %d\n", GetLastError());
}
//關閉文件
if (!CloseHandle(hFile)){
printf("關閉文件對象失敗: %d\n", GetLastError());
}
getchar();
return 0;
}