File Mapping

 http://msdn2.microsoft.com/en-us/library/aa366556(VS.85).aspx

上面是msdn链接,关于File Mapping的。

简单的翻译几点:

"File mapping" 是文件内容和进程虚拟地址空间某一部分的联系,系统创建一个"file mapping object "对象来维护这种联系。

"file view "是进程用来访问文件内容的那部分虚拟地址空间。

该技术可以有效的操作大型数据文件,而不用全部都读入到内存中,多个进程也可以使用它共享数据。

进程使用指针从"file view "读取或写入数据,需要注意的是对指针的操作并不一定马上就写入文件,很可能写到cache中,可以使用" FlushViewOfFile "来强制写入。

下面是例图:

Relationship between the file on disk, a file mapping object, and a file view.


使用该技术只需要简单的几步即可,当然对于修改,删除,插入的操作就有点复杂了,但这是每种文件操作都不可避免的。

1. 使用"CreateFile"打开要操作的文件,我们需要他返回来的句柄,除了访问权限和共享模式没什么要注意的了。

2.使用"CreateFileMapping"来创建一个"filemapping"对象,这里参数size有点说道,下面要创建的file view的大小不能超过这里设置的数值,并且现在创建的对象的大小将是固定的,在后面的操作中不能变化,如果你指定的size比原文件大的话,系统会扩充你的原文件到指定大小,如果指定的size比原文件小的话,只影响下面将要创建的file view的最大值。现在指定的大小并不会产生任何资源消耗。
所以对于读文件完全可以把size设成0这样就会按原文件的大小来创建"filemapping"对象。注意,文件的大小不能为0,否则回返回"ERROR_FILE_INVALID"。
对于写文件操作的话,你需要对最终的文件长度有个估算,然后以估算的大小来创建,否则你就没地方追加数据了。
如果你要view的那部分不在文件的开头,那么你创建的size就应该是,view的大小加上在文件中的偏移量。举例说明:在文件的128K的位置开始要读1K的数据,那么你创建的size就应该是128 + 1 = 129K,详见msdn链接。
http://msdn2.microsoft.com/en-us/library/aa366548(VS.85).aspx

3. 使用"MapViewOfFile"把数据map到内存地址空间,这里要注意的是offset必须是"allocation granularity"的整数倍,使用"GetSystemInfo"来获取。返回的指针就是我们要操作的对象了。

4.善后工作使用"UnmapViewOfFile","CloseHandle","SetEndOfFile"这些即可。

简单吧就这些,要是能完美的实现增,删,改,查的话,那就没得说了,使用中读取比较好弄,可以用memchr搜索想要的东西,然后判断后面的字符,或者赋给string然后操作,删除某一块,也还过得去,需要用2个view来回考数据,插入就不知道了,除了在复制一份还有什么好方法,如果谁知道,麻烦你留个言,谢谢了先。欢迎就此问题讨论。

 

### 文件映射 (File Mapping) 的概念 文件映射是一种允许程序通过虚拟内存机制访问磁盘上的文件的技术。它使得应用程序可以像操作内存一样操作文件数据,而无需显式的调用传统的 I/O 函数[^1]。 具体来说,文件映射会将一个文件的内容映射到进程的地址空间中,从而让程序可以通过指针直接读取或修改这些内容。这种技术不仅简化了文件的操作方式,还显著提高了效率,因为底层的数据交换是由操作系统自动管理的。 --- ### 实现过程概述 为了实现文件映射功能,通常需要完成以下几个核心步骤: #### 1. **创建或打开目标文件** 需要先指定一个物理存储设备上的文件作为基础资源。这一步骤涉及创建或者打开一个文件句柄,用于后续操作。此句柄代表的是实际存在于磁盘上的文件对象。 #### 2. **建立文件映射内核对象** 接下来,需定义并初始化一个文件映射对象。这个对象描述了整个文件区域的属性及其预期用途(只读、可写还是共享)。同时也会告知系统所需的缓冲区大小以及具体的访问模式等参数设置。 #### 3. **映射视图至进程地址空间** 最终阶段就是把上述准备好的部分或全部文件范围投射进当前运行线程的有效地址范围内。一旦成功,则任何对该区域内位置的常规内存引用实际上都会触发对应硬盘扇区加载动作。 以下是基于 Windows 平台的一个简单示例代码展示如何利用 API 完成以上流程: ```cpp #include <windows.h> #include <tchar.h> int _tmain() { HANDLE hFile, hMap; LPCTSTR pBuf; // Step 1: Create or open a file. hFile = CreateFile(_T("data.txt"), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { /* Handle error */ } // Step 2: Create the file mapping object. hMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL); if (!hMap) { /* Handle error and close handles as necessary*/ } // Step 3: Map view of file into address space. pBuf = (LPTSTR)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, BUF_SIZE); if(!pBuf){/*Handle Error*/} // Now you can use pBuf like normal memory pointer. UnmapViewOfFile(pBuf); CloseHandle(hMap); CloseHandle(hFile); } ``` 这段 C++ 程序片段展示了基本框架下怎样一步步构建起完整的文件映射环境,并提供了初步错误处理逻辑以便于调试期间发现问题所在之处[^2]。 --- ### 应用场景分析 由于其高效性和便捷性的特点,在许多领域都有广泛的应用价值: - 数据库管理系统经常采用这种方式来优化查询响应速度; - 多媒体播放器可能借助于此方法快速定位视频帧序列; - 编辑大型文档软件也可能依赖此类手段提升用户体验流畅度等等。 总之,合理运用文件映射能够极大地改善系统的整体表现力,尤其是在面对海量数据集时尤为明显。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值