内存映射文件并不是简单的文件I/O操作,实际用到了Windows的核心编程技术--内存管理。所以,如果想对内存映射文件有更深刻的认识,必须对Windows操作系统的内存管理机制有清楚的认识,内存管理的相关知识非常复杂,超出了本文的讨论范畴,在此就不再赘述,感兴趣的读者可以参阅其他相关书籍。下面给出使用内存映射文件的一般方法:
Step1.通过CreateFile()函数来创建或打开一个文件内核对象,这个对象标识了磁盘上将要用作内存映射文件的文件。在用CreateFile()将文件映像在物理存储器的位置通告给操作系统后,只指定了映像文件的路径,映像的长度还没有指定
Step2.通过CreateFileMapping()函数来创建一个文件映射内核对象以告诉系统文件的尺寸以及访问文件的方式
Step3.通过MapViewOfFile()函数负责通过系统的管理而将文件映射对象的全部或部分映射到进程地址空间
step4. 通过FlushViewOfFile()函数将内存映像保存到本地文件
step5.通过UnmapViewOfFile()完成从进程的地址空间撤消文件数据的映像、通过CloseHandle()关闭前面创建的文件映射对象和文件对象
1.将数据内存保存为内存映像文件,代码段示例:
std::string strFileName = "1.mtp";
int nLen = 1024;
unsigned char* pBuf = new unsigned char[nLen];
memset(pBuf, 128, nLen];
HANDLE hFile = nullptr;
HANDLE hFileMap = nullptr;
unsigned char* pFileData = nullptr;
size_t origsize = strFileName.length() + 1;
size_t convertedChars = 0;
wchar_t *wcstring = (wchar_t *)malloc(sizeof(wchar_t)*(strFileName.length() - 1));
mbstowcs_s(&convertedChars, wcstring, origsize, strFileName.c_str(), _TRUNCATE);
hFile = CreateFile(wcstring, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
return false;
}
hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0,nLen, NULL);
pFileData = (unsigned char*)MapViewOfFile(hFileMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
if (pFileData == nullptr)
{
UnmapViewOfFile(pFileData);
CloseHandle(hFileMap);
CloseHandle(hFile);
remove(strFileName.c_str());
return false;
}
memcpy(pFileData, pBuf,nLen);
FlushViewOfFile(pFileData,nLen);//将数据写到硬盘
UnmapViewOfFile(pFileData);
CloseHandle(hFileMap);
CloseHandle(hFile);
2.将本地的内存映像文件加载到内存中,示例代码段:
std::string strFileName = "1.mtp"
HANDLE hFile = nullptr;
HANDLE hFileMap = nullptr;
unsigned char* pFileData = nullptr;//读取得到的内存
unsigned long FileSize = 0;
size_t origsize = strFileName.length() + 1;
size_t convertedChars = 0;
wchar_t *wcstring = (wchar_t *)malloc(sizeof(wchar_t)*(strFileName.length() - 1));
mbstowcs_s(&convertedChars, wcstring, origsize, strFileName.c_str(), _TRUNCATE);
hFile = CreateFile(wcstring, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
if (hFileCT == INVALID_HANDLE_VALUE)
{
return false;
}
FileSize = GetFileSize(hFile, NULL);
hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
if (hFileMapCT == NULL)
{
return false;
}
pFileData = (unsigned char*)MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);
if (pFileData == NULL)
{
return false;
}