您的位置:首页 > 其它

通过内存映射文件操作大型文件

2014-10-16 00:20 295 查看
参考来源:http://www.cnblogs.com/stuarts/archive/2010/07/08/1773844.htm 内存映射,说简单点就像符号链接(类似比喻,大家匆喷。。。)一样。它可以在不增大过多内存开销的同时,又能快速(来自网上:比I/O读写要快20倍)处理GB级别以上的大型文件。实现步骤:1.CreateFile2.CreateFileMapping3.MapViewOfFile通过MapViewOfiFile便可得到一个可以直接操作文件的内存地址。注意:
LPVOID MapViewOfFile(
HANDLE hFileMappingObject,   // handle to file-mapping object
  DWORD dwDesiredAccess,       // access mode
  DWORD dwFileOffsetHigh,      // high-order DWORD of offset
  DWORD dwFileOffsetLow,       // low-order DWORD of offset
  SIZE_T dwNumberOfBytesToMap  // number of bytes to map
);
第五个参数,dwNumberOfBytesToMap指定要映射的字节大小,需由内存分配粒度的值乘以1000得到(如果文件大小小于乘积,则使用实际文件大小)。
详细原理自行谷歌。
由此可知,当对文件的操作达到或接近文件末端时,须以下一块文件的偏移值或当前指针位置加一的值重新映射。

关键代码:
提取于文章开头来源网址的博文中(在此表示感谢原博主!)
// 得到hFileMap之后,hFileMap = CreateFileMapping()
if (hFileMap == NULL)
{
printf("创建文件映射对象失败,错误代码:%drn", GetLastError());
return -1;
}
// 得到内存分配粒度
SYSTEM_INFO SysInfo;
GetSystemInfo(&SysInfo);
DWORD dwGran = SysInfo.dwAllocationGranularity;
// 得到文件尺寸
DWORD dwFileSizeHigh;
__int64 qwFileSize = GetFileSize(hFile, &dwFileSizeHigh);
qwFileSize |= (((__int64)dwFileSizeHigh) << 32);
// 关闭文件对象
CloseHandle(hFile);
// 偏移地址
__int64 qwFileOffset = 0;
// 块大小:在映射过程中设定每次映射的块大小为1000倍的分配粒度
DWORD dwBlockBytes = 1000 * dwGran;
if (qwFileSize < 1000 * dwGran)
dwBlockBytes = (DWORD)qwFileSize;
while (qwFileSize > 0)
{
// 映射视图,LPVOID可根据需要转换成实际类型
LPVOID lpbMapAddress = (LPVOID)MapViewOfFile(hFileMap,FILE_MAP_ALL_ACCESS,
(DWORD)(qwFileOffset >> 32) , (DWORD)(qwFileOffset & 0xFFFFFFFF), /*不同长度的位运算右端对齐*/
dwBlockBytes);
if (lpbMapAddress == NULL)
{
printf("映射文件映射失败,错误代码:%drn", GetLastError());
return -1;
}
const int NUMBER_MAX_LENGTH = 6;
// 对映射的视图进行访问
char temp[NUMBER_MAX_LENGTH + 1] = {0};
int number = 0;
//直接操作内存lpbMapAddress,此时lpbMapAddress即为一个内存地址,但为磁盘文件的分块映射

// 对文件的详细操作。。。

// 撤消文件映像
UnmapViewOfFile(lpbMapAddress);
// 修正参数,为映射下一块文件作准备
qwFileOffset += dwBlockBytes;
qwFileSize -= dwBlockBytes;
}
// 关闭文件映射对象句柄
CloseHandle(hFileMap);
return 0;
}
现学,只得其皮毛。

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: