FileMapping文件映射的优势
如果是32 位的OS,一般HANDLE 是一个4个字节,所以每次移动只能4个字节,速度表较慢,能不能更快呢?下面让我们看一下文件映射的优势。
(1) (CreateFileMapping) 创建一个文件映射内核对象。
(2) (MapViewofFile) 将一个文件映射对象映射到当前应用程序的地址空间。
---------------------------------------------------------------------------------------------------------
CreateFileMapping : 创建一个新的文件映射内核对象。
HANDLE CreateFileMapping(
HANDLE hFile, // 物理文件句柄
LPSECURITY_ATTRIBUTE lpAttritutes, // 安全属性
DWORD flProtect, // 保护设置
DWORD dwMaximumSizeHigh, // 高位文件大小
DWORD dwMaximumSizeLow, // 低文件大小
LPCTSTR lpName // 共享内存名称
);
1) 物理文件句柄
可以通过CreateFile()函数获得的物理文件句柄, 如果需要创建一个物理文件无关的内存映射, 将它设置成为 0xFFFFFFFF(INVALID_HANDLE_VALUE).
2) 保护设置
一般设置NULL就可以了, 使用默认的安全配置,
PAGE_READONLY 以只读方式打开映射
PAGE_READWRITE 以可读、可写方式打开映射
PAGE_WRITECOPY 为写操作留下备份
可组合使用下述一个或多个常数
SEC_COMMIT 为文件映射一个小节中的所有页分配内存
SEC_IMAGE 文件是个可执行文件
SEC_RESERVE 为没有分配实际内存的一个小节保留虚拟内存空间
3) 共享内存名称
为了对内存进行互斥访问,设置了一个互斥句柄, 而名称选择和命名共享内存同名, 他们使用共同的namespace,会导致错误.
返回值:
Long,新建文件映射对象的句柄。不成功,ERROR_ALREADY_EXISTS。
---------------------------------------------------------------------------------------------------------
MapViewofFile 将一个文件映射对象映射到当前应用程序的地址空间,允许我们指定一个基址来进行映射.
LPVOID WINAPI MapViewOfFile(
HANDLE hFileMappingObject, // 文件映像对象句柄
DWORD dwDesiredAccess, // 映射对象的文件数据的访问方式
DWORD dwFileOffsetHigh, // 文件映射起始偏移的高32位
DWORD dwFileOffsetLow, // 文件映射起始偏移的低32位,文件偏移量必须是系统分配粒度的整数倍
SIZE_T dwNumberOfBytesToMap // 指定映射文件的字节数
);
1) 文件映像对象句柄
CreateFileMapping()返回的文件映像对象句柄.
2)映射对象的文件数据的访问方式
FILE_MAP_WRITE 映射可读可写。文件映射对象必须通过PAGE_READWRITE访问创建
FILE_MAP_READ 映射只读。文件映射对象必须通过PAGE_READ 或 PAGE_READWRITE访问创建
FILE_MAP_ALL_ACCESS 与FILE_MAP_WRITE相同
FILE_MAP_COPY 映射时保留写操作的副本
3)映射文件的字节数
用 0 映射整个文件映射对象.
注意:dwFileOffsetLow和dwFileOffsetHigh必须反映一个偏移距离,它由系统的内存分配精度决定。例如,假设系统的内存精度是64KB(即最小分配单位是64KB),则这些值必须是64KB的整数倍。大多数应用程序都简单的用0从文件的起始处开始映射。lpBaseAddress也必须是内存分配精度的整数倍
返回值:
成功,返回映射文件的开始地址值,失败,返回NULL
例子:
HANDLE m_File;
HANDLE m_Map;
HNADLE m_View;
TCHAR m_Name[MAX_PATH];
m_File = CreateFile(m_Name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); //得到文件句柄
if( m_File == INVALID_HANDLE_VALUE)
{
printf("m_File is error:%d\n", GetLastError());
return 0;
}
m_Map = CreateFileMapping(m_File, NULL, PAGE_READONLY, 0, 0, NULL); //创建一个文件映射内核对象
if(!m_Map)
{
printf("m_Map is error:%d\n", GetLastError());
return 0;
}
m_View = MapViewofFile(m_Map, FILE_MAP_READ, 0, 0, 0); //映射对象映射到当前应用程序的地址空间
if(!m_View )
{
printf("m_View is error:%d\n", GetLastError());
return 0;
}
此时,成功后就会获得到映射文件的开始地址值。