内存映射方法CreateFileMapping、MapViewOfFile、UnmapViewOfFile
日期: 2020-01-15 分类: 个人收藏 424次阅读
内存映射使用方法
1.先行打开物理文件
hFile = CreateFileCreateFile(szFileName,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
2.根据CreateFile返回的句柄创建内存映射
hMapping = CreateFileMapping(hFile,0,PAGE_READONLY,0,0,“a”);
3.将内存映射文件映射在内存中返回可操作的地址
ReadString = MapViewOfFile(hMapping,FILE_MAP_READ,0,0,0);
4.释放内存映射地址
UnmapViewOfFile(ReadString);
5.关闭文件映射句柄
CloseHandle(hMapping);
6.关闭物理文件句柄
CloseHandle(hFile);
对内存映射的操作方法步骤
CreateFileMapping 创建一个文件内核内存映射
函数原型
HANDLE CreateFileMapping(
HANDLE hFile, //物理文件句柄
LPSECURITY_ATTRIBUTES lpAttributes, //安全设置
DWORD flProtect, //保护设置
DWORD dwMaximumSizeHigh, //高位文件大小
DWORD dwMaximumSizeLow, //低位文件大小
LPCTSTR lpName //共享内存名称
);
返回值:是一个句柄HANDLE,这个句柄用于MapViewOfFile函数和UnmapViewOfFile函数使用
返回值有可能出错,出错的可能情况如下几种GetLastError()取得:
ERROR_FILE_INVALID 物理文件句柄失败
ERROR_INVALID_HANDLE 创建文件内核映射内存失败
ERROR_ALREADY_EXISTS 共享内存名称已存在,重名了
函数参数列表:
1.HANDLE hFile, //物理文件句柄,使用CreateFile取得物理文件句柄,如果创建的内存映射和物理文件无关,可以将参数设置为INVALID_HANDLE_VALUE,脱离与实体文件的关联
2.LPSECURITY_ATTRIBUTES lpAttributes, //安全设置
通常情况使用默认的安全属性NULL,如果是win2k系统映射内存给网络使用时需要设置安全属性
3.DWORD flProtect, //保护设置
PAGE_READONLY 以只读方式打开映射
PAGE_READWRITE 以可读、可写方式打开映射
PAGE_WRITECOPY 为写操作留下备份
可组合使用下述一个或多个常数:
SEC_COMMIT 为文件映射一个小节中的所有页分配内存
SEC_IMAGE 文件是个可执行文件
SEC_RESERVE 为没有分配实际内存的一个小节保留虚拟内存空间
4.DWORD dwMaximumSizeHigh, //高位文件大小
5.DWORD dwMaximumSizeLow, //低位文件大小
以上两个参数由两个32位表示一个64位的文件,手动指定内存大小,如果都设置为0,那么就表示用物理文件的实际大小进行内存映射
6.LPCTSTR lpName //共享内存名称
如果设置名称,那么内存映射将和其他进程共享内存使用,共享方式是用共享内存名称来实现的。
MapViewOfFile 将一个文件映射对象映射到当前应用程序的地址空间。
MapViewOfFileEx允许我们指定一个基本地址来进行映射。
函数原型
LPVOID MapViewOfFile(
HANDLE hFileMappingObject, //内存映射文件产生句柄
DWORD dwDesiredAccess, //对文件映射访问的权限
DWORD dwFileOffsetHigh, //偏移量高位
DWORD dwFileOffsetLow,//偏移量低位
DWORD dwNumberOfBytesToMap //指定要映射的文件的字节数。如果将此参数设置为零,则将映射整个文件。
);
返回值:
如果函数成功将返回内存映射的地址;失败使用GetLastError()取得
参数列表说明:
1.HANDLE hFileMappingObject 由CreateFileMapping创建句柄
2.DWORD dwDesiredAccess 映射对象的文件数据的访问方式,而且同样要与CreateFileMapping()函数所设置的保护属性相匹配。 可取以下值:
映射对象的文件数据的访问方式,而且同样要与CreateFileMapping()函数所设置的保护属性相匹配。 可取以下值:
FILE_MAP_ALL_ACCESS 等价于CreateFileMapping的 FILE_MAP_WRITE|FILE_MAP_READ. 文件映射对象被创建时必须指定PAGE_READWRITE 选项.
FILE_MAP_COPY 可以读取和写入文件.写入操作会导致系统为该页面创建一份副本.在调用CreateFileMapping时必须传入PAGE_WRITECOPY保护属性.
FILE_MAP_EXECUTE 可以将文件中的数据作为代码来执行.在调用CreateFileMapping时可以传入PAGE_EXECUTE_READWRITE或PAGE_EXECUTE_READ保护属性.
FILE_MAP_READ 可以读取文件.在调用CreateFileMapping时可以传入PAGE_READONLY或PAGE_READWRITE保护属性.
FILE_MAP_WRITE 可以读取和写入文件.在调用CreateFileMapping时必须传入PAGE_READWRITE保护属性.
3.DWORD dwFileOffsetHigh, //偏移量高位
4. DWORD dwFileOffsetLow,//偏移量低位
5. DWORD dwNumberOfBytesToMap //指定要映射的文件的字节数。
如果将此参数设置为零,则将映射整个文件。
UnmapViewOfFile停止文件映射
BOOL WINAPI UnmapViewOfFile(_In_LPCVOID lpBaseAddress);
这里的lpBaseAddress是由MapViewOfFile产生的内存地址
如下例子:
#include <windows.h>
#include <stdio.h>
BOOL ReadFileToMemMapping(LPCTSTR szFileName);
int main(int argc,LPTSTR argv[])
{
if(argc < 2)
{
printf("用法错误,Usage: %s 文件名 ...\n",argv[0]);
return 0;
}
for(int i = 1; i < argc;i++)
{
ReadFileToMemMapping(argv[i]);
}
return 0;
}
BOOL ReadFileToMemMapping(LPCTSTR szFileName)
{
BOOL bRet = szFileName && lstrlen(szFileName);
HANDLE hFile = CreateFile(szFileName,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
HANDLE hMapping;
LPVOID ReadString;
if(!bRet)
{
printf("文件名为空!\n");
return bRet;
}
if(hFile == INVALID_HANDLE_VALUE)
{
printf("文件:%s打开失败!\n",szFileName);
return bRet;
}
hMapping = CreateFileMapping(hFile,0,PAGE_READONLY,0,0,"a");
if(hMapping == INVALID_HANDLE_VALUE)
{
printf("文件映射打开失败!\n");
CloseHandle(hFile);
return false;
}
ReadString = MapViewOfFile(hMapping,FILE_MAP_READ,0,0,0);
if(!ReadString)
{
printf("读取文件映射数据失败!\n");
CloseHandle(hMapping);
CloseHandle(hFile);
return false;
}
printf("我读到的内存文件为%s\n",(LPTSTR)ReadString);
UnmapViewOfFile(ReadString);
CloseHandle(hMapping);
CloseHandle(hFile);
return bRet;
}
除特别声明,本站所有文章均为原创,如需转载请以超级链接形式注明出处:SmartCat's Blog
标签:win32 API
上一篇: 电脑连上手机热点后上不了网
精华推荐