参考来源:http://www.cnblogs.com/stuarts/archive/2010/07/08/1773844.htm
内存映射,说简单点就像符号链接(类似比喻,大家匆喷。。。)一样。它可以在不增大过多内存开销的同时,又能快速(来自网上:比I/O读写要快20倍)处理GB级别以上的大型文件。
实现步骤:
1.CreateFile
2.CreateFileMapping
3.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得到(如果文件大小小于乘积,则使用实际文件大小)。
详细原理自行谷歌。
由此可知,当对文件的操作达到或接近文件末端时,须以下一块文件的偏移值或当前指针位置加一的值重新映射。
关键代码:
提取于文章开头来源网址的博文中(在此表示感谢原博主!)
1 // 得到hFileMap之后,hFileMap = CreateFileMapping() 2 if (hFileMap == NULL) 3 { 4 printf("创建文件映射对象失败,错误代码:%drn", GetLastError()); 5 return -1; 6 } 7 // 得到内存分配粒度 8 SYSTEM_INFO SysInfo; 9 GetSystemInfo(&SysInfo); 10 DWORD dwGran = SysInfo.dwAllocationGranularity; 11 // 得到文件尺寸 12 DWORD dwFileSizeHigh; 13 __int64 qwFileSize = GetFileSize(hFile, &dwFileSizeHigh); 14 qwFileSize |= (((__int64)dwFileSizeHigh) << 32); 15 // 关闭文件对象 16 CloseHandle(hFile); 17 // 偏移地址 18 __int64 qwFileOffset = 0; 19 // 块大小:在映射过程中设定每次映射的块大小为1000倍的分配粒度 20 DWORD dwBlockBytes = 1000 * dwGran; 21 if (qwFileSize < 1000 * dwGran) 22 dwBlockBytes = (DWORD)qwFileSize; 23 while (qwFileSize > 0) 24 { 25 // 映射视图,LPVOID可根据需要转换成实际类型 26 LPVOID lpbMapAddress = (LPVOID)MapViewOfFile(hFileMap,FILE_MAP_ALL_ACCESS, 27 (DWORD)(qwFileOffset >> 32) , (DWORD)(qwFileOffset & 0xFFFFFFFF), /*不同长度的位运算右端对齐*/ 28 dwBlockBytes); 29 if (lpbMapAddress == NULL) 30 { 31 printf("映射文件映射失败,错误代码:%drn", GetLastError()); 32 return -1; 33 } 34 const int NUMBER_MAX_LENGTH = 6; 35 // 对映射的视图进行访问 36 char temp[NUMBER_MAX_LENGTH + 1] = {0}; 37 int number = 0; 38 //直接操作内存lpbMapAddress,此时lpbMapAddress即为一个内存地址,但为磁盘文件的分块映射 39 40 // 对文件的详细操作。。。 41 42 // 撤消文件映像 43 UnmapViewOfFile(lpbMapAddress); 44 // 修正参数,为映射下一块文件作准备 45 qwFileOffset += dwBlockBytes; 46 qwFileSize -= dwBlockBytes; 47 } 48 // 关闭文件映射对象句柄 49 CloseHandle(hFileMap); 50 return 0; 51 }
现学,只得其皮毛。