首先通過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);