m_hFile = m_file.m_hFile;
ULONGLONG dwFileSize = GetFileSize(m_hFile, NULL);
//得到的系统页大小是4k,但大文件映射部分块需要偏移以64k对齐。
m_SyspageSize = 65536;
定义映射的起始偏移和映射的大小
ULONGLONG UllOffset = dwNodeIndex * 0x640 + m_dwFnmOffset + sizeof(DirFileTreeHead);
UllOffset = (UllOffset / m_SyspageSize) * m_SyspageSize;
DWORD dwSizeToMap = 65536;
//dwSizeToMap = dwSizeToMap / m_SyspageSize * m_SyspageSize;
m_hMapping = CreateFileMapping(
m_hFile,
NULL,
PAGE_READWRITE,
HIDWORD(dwFileSize),
LODWORD(dwFileSize),
NULL);
m_lpFile = (BYTE*)MapViewOfFile(
m_hMapping,
FILE_MAP_READ | FILE_MAP_WRITE,
HIDWORD(UllOffset),
LODWORD(UllOffset),
dwSizeToMap + 0x640);//一个节点的大小为0x640,
DWORD dwError = GetLastError();
DWORD dwError1 = dwError;
最近写项目时使用文件映射遇到的一个问题。在映射大文件时,并不能一次将全部文件映射到内存中,毕竟内存空间有限^_^,所以需要分块映射,幸好“万能的微软”肯定已经考虑了这个问题的,我们可以通过改变MapViewOfFile的参数来设置需要映射文件的偏移和指定大小,但问题就出在参数的问题上,它并不是能够任意去指定的,需要以系统页大小去对齐。微软官方文档是这么解释的,英文文档我也看过,是一样的解释。那么让我们看看SYSTEM_INFO的结构和什么是系统的内存分配粒度。
typedef struct _SYSTEM_INFO {
union {
DWORD dwOemId;
struct {
WORD wProcessorArchitecture;
WORD wReserved;
} DUMMYSTRUCTNAME;
} DUMMYUNIONNAME;
DWORD dwPageSize;
LPVOID lpMinimumApplicationAddress;
LPVOID lpMaximumApplicationAddress;
DWORD_PTR dwActiveProcessorMask;
DWORD dwNumberOfProcessors;
DWORD dwProcessorType;
DWORD dwAllocationGranularity;
WORD wProcessorLevel;
WORD wProcessorRevision;
} SYSTEM_INFO, *LPSYSTEM_INFO;
主要看dwPageSize这个参数,文档是这么说的。
那么问题好像就解决了,呵呵呵呵。所以想当然的我使用dwPageSize做了偏移对齐。结果每次只有第一次MapViewOfFile返回的指针是有值的。哦不.....,我的耐心已经要被消耗完了(看来我的耐心有点差,呵呵呵呵o(* ̄︶ ̄*)o)。根据getlasterror返回的错误码0x46c,进行搜索。
得到的结果是【0x46c|1132】-指定的基址或文件偏移量没有适当对齐。那就很奇怪啊,明明不就是对齐了吗?进行了自我怀疑,就这么几行破代码又看又改(he,tui)。直到看见了
内存映射文件 错误码(1132、5)_getlasterror 1132_xian_wwq的博客-CSDN博客
用MapViewOfFile处理大文件-内存不足_mapviewoffile指定读取的起始位置_滴水梵音的博客-CSDN博客z
这两篇博客,原来对齐的应该是
SYSTEM_INFO sinf;
GetSystemInfo(&sinf);
DWORD dwAllocationGranularity = sinf.dwAllocationGranularity;这个参数。
感觉自己试撒币....。问题解决,偏移应该是以64k对齐。