六、內存映射文件
1.使用Mapping File提高文件讀寫的效率 /* ********************************************************************* * file_map.c 使用Mapping File提高文件讀寫效率 * *********************************************************************/ /*頭文件*/ #include <Windows.h> #include <stdio.h> /*預處理聲明*/ #define BUFFSIZE 1024 //文件內存大小 #define FILE_MAP_START 0x28804 //文件映射的起始位置 /*全局變量*/ LPTSTR lpcTheFile = TEXT("test.dat"); //文件名 /* ******************************************************************** * int main(void) * 功能:演示使用文件mapping * 返回值:0代表執行完成,1代表發生錯誤 * ********************************************************************/ int main(void) { HANDLE hMapFile; //文件內存映射區域的句柄 HANDLE hFile; //文件句柄 DWORD dBytesWritten; //寫入的字節數 DWORD dwFileSize; //文件大小 DWORD dwFileMapSize; // 文件映射的大小 DWORD dwMapViewSize; // 視圖(view)的大小 DWORD dwFileMapStart; // 文件映射視圖的起始位置 DWORD dwSysGran; // 系統內存分配的粒度 SYSTEM_INFO SysInfo; // 系統信息 LPVOID lpMapAddress; // 內存映射區域的起始位置 PCHAR pData; // 數據 INT i; // 循環變量 INT iData; INT iViewDelta; BYTE cMapBuffer[32]; //存儲從mapping中計出的數據 //創建一個文件 hFile = CreateFile( lpcTheFile, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); //判斷文件是否創建成功 if (hFile == INVALID_HANDLE_VALUE) { printf("CreateFile error\n",GetLastError); return 1; } //一次寫入整數,一共寫入65535個整數 //在32平台上,大小為65535*4字節(在32位平台下,一個整形為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對象的大小,高位 dwFileMapSize, //mapping對象的大小,低位 NULL //mapping對象的名字 ); if (hMapFile == NULL) { printf("CreateFileMapping error :%d\n",GetLastError()); return 1; } //映射View lpMapAddress = MapViewOfFile( hMapFile, //mapping對象句柄 FILE_MAP_ALL_ACCESS, //可讀、可寫 0, //映射的文件偏移,高位 dwFileMapStart, //映射的文件偏移,低位 dwMapViewSize //映射到View的數據大小 ); if (lpMapAddress == NULL) { printf("NapViewOfFile error :%d\n",GetLastError()); return 1; } printf("文件 map view 相對於文件的起始位置:0x%x\n",dwFileMapStart); printf("文件map view 的大小:x%x\n",dwFileMapSize); printf("文件Mapping對象的大小:x%x\n",dwFileMapSize); printf("從相對於map view 0x%x字節的位置讀取數據,",iViewDelta); //將指向數據的指針偏移,到達我們關心的地方 pData = (PCHAR)lpMapAddress + iViewDelta; //讀取數據,復制給變量 iData = *(PINT)pData; //顯示讀取數據 printf("為:x%.8x\n",iData); //從mapping中復制數據 CopyMemory(cMapBuffer,lpMapAddress,32); printf("lpMapAddress 起始字節是:"); for ( i = 0; i < 32; i++) { printf("0x%.2x",cMapBuffer[i]); } //將mapping的前32個字節用xff填充 FillMemory(lpMapAddress,32,(BYTE)0xff); //將映射的數據寫回硬盤 FlushViewOfFile(lpMapAddress,dwMapViewSize); printf("\n已經將lpMapAddress開始的字節使用xff填充。\n"); //關閉mapping對象 if (!CloseHandle(hMapFile)) { printf("\nClosing the mapping obiect error %d!",GetLastError()); } //關閉文件 if (!CloseHandle(hFile)) { printf("\nError %ld occured closing the file !",GetLastError()); } getchar(); return 0; }2.通過Mapping File在進程間傳遞數據