內存映射文件處理大文件

首先通過GetFileSize()得到被處理文件長度(64位)的高32位和低32位值。然後在映射過程中設定每次映射的塊大小爲1000倍的分配粒度(系統的數據分塊大小),如果文件長度小於1000倍的分配粒度時則將塊大小設置爲文件的實際長度。在處理過程中由映射、訪問、撤消映射構成了一個循環處理。其中,每處理完一個文件塊後都通過關閉文件映射對象來對每個文件塊進行整理。CreateFileMapping()、MapViewOfFile()等函數是專門用來進行內存文件映射處理用的。
        // 創建文件對象
 HANDLE hFile = ::CreateFile(strFile, GENERIC_READ,FILE_SHARE_READ, NULL, 
  OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL);
 if (hFile == INVALID_HANDLE_VALUE)
 {
  TRACE("創建文件對象失敗,錯誤代碼:%d\r\n", GetLastError());
  return;
 }
 // 創建文件映射對象
 HANDLE hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
 if (hFileMap == NULL)
 {
  TRACE("創建文件映射對象失敗,錯誤代碼:%d\r\n", GetLastError());  
  return;
 }
 // 得到系統分配粒度
 SYSTEM_INFO SysInfo;
 GetSystemInfo(&SysInfo);
 DWORD dwGran = SysInfo.dwAllocationGranularity;
 // 得到文件尺寸
 DWORD dwFileSizeHigh;
 __int64 qwFileSize = GetFileSize(hFile, &dwFileSizeHigh);
 qwFileSize |= (((__int64)dwFileSizeHigh) << 32);///MSDN
 // 偏移地址 
 __int64 qwFileOffset = 0;
 __int64 T_newmap = 900 * dwGran;
 // 塊大小
 DWORD dwBlockBytes = 1000 * dwGran;//文件數據分段大小
 if (qwFileSize - qwFileOffset < dwBlockBytes)
  dwBlockBytes = (DWORD)qwFileSize;
 // 映射視圖
 char *lpbMapAddress = (char *)MapViewOfFile(hFileMap,FILE_MAP_READ,
  (DWORD)(qwFileOffset >> 32), (DWORD)(qwFileOffset & 0xFFFFFFFF),dwBlockBytes);
 if (lpbMapAddress == NULL)
 {
  TRACE("映射文件映射失敗,錯誤代碼:%d ", GetLastError());
  return;
 } 
 // 關閉文件對象
 CloseHandle(hFile); 
 ///////////讀文件數據
 while(qwFileOffset < qwFileSize)
 {
  /********************            讀文件             ***************************/  
  //read_eh(&lpbMapAddress)讀取已映射到內存的數據,
  //並將文件指針作相應後移(lpbMapAddress++),返回指針偏移量
  qwFileOffset = qwFileOffset + read_eh(&lpbMapAddress); //修改偏移量
  if (qwFileOffset > T_newmap)
  {//當數據讀到90%時,爲防數據溢出,需要映射在其後的數據  T_newmap
   UnmapViewOfFile(lpbMapAddress);//釋放當前映射
   if ((DWORD)(qwFileSize - T_newmap) < dwBlockBytes)
   dwBlockBytes = (DWORD)(qwFileSize - T_newmap);
   lpbMapAddress = (char *)MapViewOfFile(hFileMap,FILE_MAP_READ,
   (DWORD)(T_newmap >> 32), (DWORD)(T_newmap & 0xFFFFFFFF),dwBlockBytes);
   // 修正參數
   lpbMapAddress = lpbMapAddress + qwFileOffset - T_newmap;
   T_newmap =T_newmap  + 900 * dwGran;
   if (lpbMapAddress == NULL)
   {
    TRACE("映射文件映射失敗,錯誤代碼:%d ", GetLastError());
    return;
   } 
  }
 }
 //釋放最後數據塊映射
 UnmapViewOfFile(lpbMapAddress);
 // 關閉文件映射對象句柄
 CloseHandle(hFileMap); 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章