SDK使用 Mapping File 提高文件讀寫效率

/*使用 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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章