您的位置:首页 > 其它

用MapViewOfFile处理大文件-内存不足(转帖学习)

2010-09-28 15:57 459 查看
用MapViewOfFile处理大文件时,如果文件过大,如400M,则无法一次性映射入内存,否则会出现1132错误,即内存不足。原因可能为操作系统无法找到连续的内存。因此需要通过分页的方式,逐页将文件内容映射到内存。
相关资料:
LPVOID
MapViewOfFile(HANDLE hFileMappingObject,

  DWORD dwDesiredAccess,

  DWORD dwFileOffsetHigh,

  DWORD dwFileOffsetLow,

  DWORD dwNumberOfBytesToMap);

  MapViewOfFile()函数负责把文件数据映射到进程的地址空间,参数hFileMappingObject为
CreateFileMapping()返回的文件映像对象句柄。参数dwDesiredAccess则再次指定了对文件数据的访问方式,而且同样要与
CreateFileMapping()函数所设置的保护属性相匹配。虽然这里一再对保护属性进行重复设置看似多余,但却可以使应用程序能更多的对数据的保护属性实行有效控制。MapViewOfFile()函数允许全部或部分映射文件,在映射时,需要指定数据文件的偏移地址以及待映射的长度。其中,文件的偏移地址由DWORD型的参数dwFileOffsetHigh和dwFileOffsetLow组成的64位值来指定,而且必须是操作系统的分配粒度的整数倍,对于Windows操作系统,分配粒度固定为64KB。当然,也可以通过如下代码来动态获取当前操作系统的分配粒度:

  SYSTEM_INFO sinf;

  GetSystemInfo(&sinf);

  DWORD dwAllocationGranularity = sinf.dwAllocationGranularity;

  参数dwNumberOfBytesToMap指定了数据文件的映射长度,这里需要特别指出的是,对于Windows
9x操作系统,如果MapViewOfFile()无法找到足够大的区域来存放整个文件映射对象,将返回空值(NULL);但是在Windows
2000下,MapViewOfFile()只需要为必要的视图找到足够大的一个区域即可,而无须考虑整个文件映射对象的大小。

由此看出,分页映射文件时,每页的起始位置startpos,必须为64K的整数倍。

HANDLE
hFile=::CreateFile("c://111.dwf",GENERIC_READ,FILE_SHARE_READ |
FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_READONLY,NULL);

////////////////////////////////////////////////////////////////////
//
CreateFileMapping 的dwMaximumsize必须设置为0,否则MapViewOfFile中offset>0时,映射失败
HANDLE
m_hCurFileMap =
CreateFileMapping
( hFile, NULL, PAGE_READONLY, 0, 0, NULL );

DWORD offset=64*1024;
LPVOID
m_pReadBuffer=MapViewOfFile(m_hCurFileMap,FILE_MAP_READ,

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