/*使用 Mapping File 提高文件讀寫效率*/
/*頭文件*/
#include<windows.h>
#include<stdio.h>
/*預處理申明*/
#define BUFFSIZE 1024 //內存大小
#define FILE_MAP_START 0x28804 //文件映射的起始位置
/*全局變量*/
LPSTR lpcTheFile = TEXT("test.bat"); //文件名
/*********************************************
//int main(void)
//功能:演示使用文件mapping
//返回值:0 代表執行成功,1代表執行發生錯誤
**********************************************/
int main(void)
{
HANDLE hMapFile; //文件內存映射區域的句柄
HANDLE hFile; //文件的句柄
DWORD dByteWritten; //寫入的字節數
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]; //存儲從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字節(一個整數四個字節)
for( i=0; i<65535; i++)
{
WriteFile(hFile, &i, sizeof(i), &dByteWritten, NULL);
}
//查看寫入完成後的文件大小
dwFileSize = GetFileSize(hFile, NULL);
printf("文件的大小:%d\n",dwFileSize);
//獲取系統信息,內存分配粒度
//獲取分配粒度,進行下面的計算
//目的是爲了映射的數據與系統內存分配粒度對齊,提高內存訪問率
GetSystemInfo( &SysInfo);
dwSysGran = SysInfo.dwAllocationGranularity;
//計算mapping的起始位置
dwFileMapStart = (FILE_MAP_START / dwSysGran) * dwSysGran; // FILE_MAP_START 預定義
//計算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("MapViewOfFile error:%d\n",GetLastError());
return 1;
}
printf("文件map view 相對於文件的起始位置:0x%x\n", dwFileMapStart);
printf("文件map view 的大小:0x%x\n",dwMapViewSize);
printf("文件mapping對象的大小:0x%x\n",dwFileMapSize);
printf("從相對 map view 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個字節用xff填充
FillMemory(lpMapAddress, 32, (BYTE)0xff);
//將映射的數據寫回到硬盤上
FlushViewOfFile( lpMapAddress, dwMapViewSize);
printf("\n已經將lpMapAddress 開始的32字節使用xff填充。\n");
//關閉mapping對象
if(!CloseHandle(hMapFile))
{
printf("\nclose the mapping object error %d!",GetLastError());
}
//關閉文件
if(!CloseHandle(hFile))
{
printf("\nError %ld occurred closing the file!",GetLastError());
}
return 0;
}