MapViewOfFile 函数 (memoryapi.h)
将文件映射的视图映射到调用进程的地址空间中。
若要为视图指定建议的基址,请使用 MapViewOfFileEx 函数。 但是,不建议这样做。
语法
LPVOID MapViewOfFile(
[in] HANDLE hFileMappingObject,
[in] DWORD dwDesiredAccess,
[in] DWORD dwFileOffsetHigh,
[in] DWORD dwFileOffsetLow,
[in] SIZE_T dwNumberOfBytesToMap
);
parameters
[in] hFileMappingObject
文件映射对象的句柄。 CreateFileMapping 和 OpenFileMapping 函数返回此句柄。
[in] dwDesiredAccess
文件映射对象的访问类型,该对象确定页面的页面保护。 此参数可以是以下值之一,也可以是多个值的按位 OR 组合(如果适用)。
使用按位 OR,可以将上述值与这些值组合在一起。
值 | 含义 |
---|---|
|
映射文件的写入时复制视图。 文件映射对象必须已创建PAGE_READONLY、PAGE_READ_EXECUTE、PAGE_WRITECOPY、PAGE_EXECUTE_WRITECOPY、PAGE_READWRITE或PAGE_EXECUTE_READWRITE保护。
当进程写入写入时复制页时,系统会将原始页面复制到进程专用的新页。 新页面由分页文件提供支持。 对新页面的保护从写入时复制更改为读/写。 指定写入时复制访问权限时,系统将和进程提交费用用于整个视图,因为调用进程可能会写入视图中的每个页面,从而使所有页面都成为私有页面。 新页面的内容永远不会写回到原始文件,并且当视图未映射时会丢失。 |
|
映射文件的可执行视图 (映射的内存可以作为代码) 运行。 文件映射对象必须已创建 PAGE_EXECUTE_READ、 PAGE_EXECUTE_WRITECOPY或 PAGE_EXECUTE_READWRITE 保护。
Windows Server 2003 和 Windows XP: 此值从具有 SP2 的 Windows XP 和 SP1 的 Windows Server 2003 开始可用。 |
|
从 Windows 10 版本 1703 开始,此标志指定应使用大页面支持映射视图。 视图的大小必须是 GetLargePageMinimum 函数报告的大型页面大小的倍数,并且文件映射对象必须已使用 SEC_LARGE_PAGES 选项创建。 如果为 lpBaseAddress 提供非 null 值,则该值必须是 GetLargePageMinimum 的倍数。 注意: 在 Windows 10 版本 1703 之前的 OS 版本上,FILE_MAP_LARGE_PAGES标志不起作用。 在这些版本中,如果分区是使用 SEC_LARGE_PAGES标志创建的 ,则使用大页面自动映射视图。 |
|
将映射文件中的所有位置设置为控制流防护 (CFG) 的无效目标。 此标志类似于 PAGE_TARGETS_INVALID。 将此标志与执行访问权限 FILE_MAP_EXECUTE结合使用。 对这些页面中位置的任何间接调用都将失败 CFG 检查,并且进程将终止。 分配的可执行页面的默认行为是标记为 CFG 的有效调用目标。 |
对于使用 SEC_IMAGE 属性创建的文件映射对象, dwDesiredAccess 参数不起作用,应设置为任何有效值,例如 FILE_MAP_READ。
有关访问文件映射对象的详细信息,请参阅 文件映射安全性和访问权限。
[in] dwFileOffsetHigh
视图开始位置的文件偏移量的高阶 DWORD 。
[in] dwFileOffsetLow
视图开始位置的文件偏移量的低序 DWORD 。 高偏移量和低偏移量的组合必须在文件映射中指定偏移量。 它们还必须匹配系统的内存分配粒度。 也就是说,偏移量必须是分配粒度的倍数。 若要获取系统的内存分配粒度,请使用 GetSystemInfo 函数,该函数填充 SYSTEM_INFO 结构的成员。
[in] dwNumberOfBytesToMap
要映射到视图的文件映射的字节数。 所有字节都必须在 CreateFileMapping 指定的最大大小内。 如果此参数为 0 (零) ,则映射将从指定的偏移量扩展到文件映射的末尾。
返回值
如果函数成功,则返回值是映射视图的起始地址。
如果函数失败,则返回值为 NULL。 要获得更多的错误信息,请调用 GetLastError。
注解
映射文件会使文件的指定部分在调用进程的地址空间中可见。
对于大于地址空间的文件,一次只能映射文件数据的一小部分。 第一个视图完成后,可以取消映射它并映射新视图。
若要获取视图的大小,请使用 VirtualQuery 函数。
如果文件 (或文件映射对象的多个视图及其映射文件) 在指定时间包含相同的数据,则它们是 一致的 。 如果文件视图派生自由同一文件支持的任何文件映射对象,则会发生此情况。 进程可以使用 DuplicateHandle 函数将文件映射对象句柄复制到另一个进程,或者另一个进程可以使用 OpenFileMapping 函数按名称打开文件映射对象。
有一个重要例外,派生自由同一文件支持的任何文件映射对象的文件视图在特定时间是一致的或相同的。 对于进程内的视图以及由不同进程映射的视图,可以保证一致性。
异常与远程文件相关。 尽管 MapViewOfFile 适用于远程文件,但无法使其保持一致。 例如,如果两台计算机都将一个文件映射为可写文件,并且都更改了同一页,则每台计算机只看到自己对页面的写入。 在磁盘上更新数据时,不会合并数据。
不保证文件的映射视图与 ReadFile 或 WriteFile 函数访问的文件一致。
不要将指针存储在内存映射文件中;存储与文件映射基的偏移量,以便可以在任何地址使用映射。
若要防范 EXCEPTION_IN_PAGE_ERROR 异常,请使用结构化异常处理来保护任何写入或读取页面文件以外的文件的内存映射视图的代码。 有关详细信息,请参阅 从文件视图读取和写入。
通过映射视图修改文件时,上次修改时间戳可能不会自动更新。 如果需要,调用方应使用 SetFileTime 设置时间戳。
如果文件映射对象由分页文件提供支持, (调用 CreateFileMapping 并将 hFile 参数设置为 INVALID_HANDLE_VALUE) ,则分页文件必须足够大才能保存整个映射。 否则, MapViewOfFile 将失败。 由分页文件支持的文件映射对象中页面的初始内容为 0 (零) 。
创建由分页文件支持的文件映射对象时,调用方可以指定 是 mapViewOfFile 应同时保留和提交页面 (SEC_COMMIT) ,还是仅保留页面 (SEC_RESERVE) 。 映射文件会使整个映射的虚拟地址范围无法用于进程中的其他分配。 提交保留范围内的页面后,无法通过调用 VirtualFree 来释放或取消提交该页。 取消映射视图且文件映射对象关闭时,将释放保留页和提交的页。 有关详细信息,请参阅 UnmapViewOfFile 和 CloseHandle 函数。
若要拥有具有可执行权限的文件,应用程序必须使用 PAGE_EXECUTE_READWRITE 或 PAGE_EXECUTE_READ 调用 CreateFileMapping,然后使用 FILE_MAP_EXECUTE FILE_MAP_WRITE | 或 FILE_MAP_EXECUTE | FILE_MAP_READ 调用 MapViewOfFile。
在 Windows Server 2012 中,以下技术支持此功能。
技术 | 支持 |
---|---|
服务器消息块 (SMB) 3.0 协议 | 是 |
SMB 3.0 透明故障转移 (TFO) | 是 |
具有横向扩展文件共享的 SMB 3.0 (SO) | 是 |
群集共享卷文件系统 (CSV) | 是 |
弹性文件系统 (ReFS) | 是 |
暂停 CsvFs 时,此调用可能会失败,并显示一个错误,指示存在锁冲突。
示例
有关示例,请参阅 创建命名共享内存。
要求
最低受支持的客户端 | Windows XP [仅限桌面应用] |
最低受支持的服务器 | Windows Server 2003 [仅限桌面应用] |
目标平台 | Windows |
标头 | memoryapi.h (包括 Windows.h、Memoryapi.h) |
Library | onecore.lib |
DLL | Kernel32.dll |