赞
踩
与虚拟内存一样,内存映射文件可以用来保留一个地址空间的区域,并将物理存储器提交给该区域。它们之间的差别是,物理存储器来自一个已经位于磁盘上的文件,而不是系统的页文件。一旦该文件被映射,就可以访问它,就像整个文件已经加载到内存一样。
内存映射文件场景
当线程调用CreateProcess时,系统将执行下列操作步骤:
引入内存映射文件
目的:逆序一个文件的内容
方法1:一个文件,一个缓存,从文件一次性读到缓存,逆序后写回去,缺点1:无法处理大文件,缺点2:如果写回时过程异常,文件被破坏
方法2:两个文件,一个缓存,读一定大小文件内容到缓存,逆序后写入新文件,不断反复。缺点1:速度慢,缺点2:需要两个文件所占的磁盘空间
方法3:一个文件,一个缓存,读一定大小文件内容到缓存,逆序后写回去 ,缺点:如果写回时过程异常,文件被破坏
方法4:一个文件,零缓存,使用内存映射,无需分配/释放内存和加载/写回文件数据到内存:缺点:过程异常,文件被破坏
如何使用内存映射
1 创建或打开一个文件内核对象,该对象用于标识磁盘上你想用作内存映射文件的文件。
2 创建一个文件映射内核对象,告诉系统该文件的大小和你打算如何访问该文件。
3 让系统将文件映射对象的全部或一部分映射到你的进程地址空间中。
auto fileHandle = CreateFile("./123.txt", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_ALWAYS, FILE_FLAG_WRITE_THROUGH, nullptr);
if (fileHandle == INVALID_HANDLE_VALUE) {
return 0;
}
auto mapHandle = CreateFileMapping(fileHandle, nullptr, PAGE_READWRITE, 0, 100, nullptr);
if (mapHandle == nullptr) {
return 0;
}
auto pointer = MapViewOfFile(mapHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
用完后
1 告诉系统从你的进程的地址空间中撤消文件映射内核对象的映像。
2 关闭文件映射内核对象。
3 关闭文件内核对象。
UnmapViewOfFile(pointer);
CloseHandle(mapHandle);
CloseHandle(fileHandle);
如果需要确保你的更新被写入磁盘,可以强制系统将修改过的数据的一部分或全部重新写入磁盘映像中,方法是调用FlushViewOfFile函数。对于存储器是在网络上的内存映射文件来说, FlushViewOfFile能够保证文件的数据已经从工作站写入存储器。但是FlushViewOfFile不能保证正在共享文件的服务器已经将数据写入远程磁盘,因为服务器也许对文件的数据进行了高速缓存。若要保证服务器写入文件的数据,每当你为文件创建一个文件映射对象并且映射该文件映射对象的视图时,应该将FILE_FLAG_WRITE_THROUGH标志传递给CreateFile函数。如果你使用该标志打开该文件,那么只有当文件的全部数据已经存放在服务器的磁盘驱动器中的时候, FlushViewOfFile函数才返回。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。