首先通過(guò)GetFileSize()得到被處理文件長(zhǎng)度(64位)的高32位和低32位值。然后在映射過(guò)程中設(shè)定每次映射的塊大小為1000倍的分配粒度(系統(tǒng)的數(shù)據(jù)分塊大小),如果文件長(zhǎng)度小于1000倍的分配粒度時(shí)則將塊大小設(shè)置為文件的實(shí)際長(zhǎng)度。在處理過(guò)程中由映射、訪問(wèn)、撤消映射構(gòu)成了一個(gè)循環(huán)處理。其中,每處理完一個(gè)文件塊后都通過(guò)關(guān)閉文件映射對(duì)象來(lái)對(duì)每個(gè)文件塊進(jìn)行整理。CreateFileMapping()、MapViewOfFile()等函數(shù)是專門用來(lái)進(jìn)行內(nèi)存文件映射處理用的。
// 創(chuàng)建文件對(duì)象
HANDLE hFile = ::CreateFile(strFile, GENERIC_READ,FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
TRACE("創(chuàng)建文件對(duì)象失敗,錯(cuò)誤代碼:%d\r\n", GetLastError());
return;
}
// 創(chuàng)建文件映射對(duì)象
HANDLE hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
if (hFileMap == NULL)
{
TRACE("創(chuàng)建文件映射對(duì)象失敗,錯(cuò)誤代碼:%d\r\n", GetLastError());
return;
}
// 得到系統(tǒng)分配粒度
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;//文件數(shù)據(jù)分段大小
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("映射文件映射失敗,錯(cuò)誤代碼:%d ", GetLastError());
return;
}
// 關(guān)閉文件對(duì)象
CloseHandle(hFile);
///////////讀文件數(shù)據(jù)
while(qwFileOffset < qwFileSize)
{
/******************** 讀文件 ***************************/
//read_eh(&lpbMapAddress)讀取已映射到內(nèi)存的數(shù)據(jù),
//并將文件指針作相應(yīng)后移(lpbMapAddress++),返回指針偏移量
qwFileOffset = qwFileOffset + read_eh(&lpbMapAddress); //修改偏移量
if (qwFileOffset > T_newmap)
{//當(dāng)數(shù)據(jù)讀到90%時(shí),為防數(shù)據(jù)溢出,需要映射在其后的數(shù)據(jù) T_newmap
UnmapViewOfFile(lpbMapAddress);//釋放當(dāng)前映射
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);
// 修正參數(shù)
lpbMapAddress = lpbMapAddress + qwFileOffset - T_newmap;
T_newmap =T_newmap + 900 * dwGran;
if (lpbMapAddress == NULL)
{
TRACE("映射文件映射失敗,錯(cuò)誤代碼:%d ", GetLastError());
return;
}
}
}
//釋放最后數(shù)據(jù)塊映射
UnmapViewOfFile(lpbMapAddress);
// 關(guān)閉文件映射對(duì)象句柄
CloseHandle(hFileMap);