C++ CreateFileMapping 内存映射实现快速读取文件

这篇具有很好参考价值的文章主要介绍了C++ CreateFileMapping 内存映射实现快速读取文件。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、简述共享内存

共享内存的方式原理就是将一份物理内存映射到不同进程各自的虚拟地址空间上,这样每个进程都可以读取同一份数据,从而实现进程通信。因为是通过内存操作实现通信,因此是一种最高效的数据交换方法。

本文主要讲述的使用内存映射文件的目的是访问磁盘上的数据文件。你可以不必对文件执行I / O操作,并且可以不必对文件内容进行缓存。

二、函数API

1、CreateFileMapping// 创建一个内存映射文件的内核对象


HANDLE CreateFileMapping(
  HANDLE hFile,                                      // 文件句柄,填写 INVALID_HANDLE_VALUE
  LPSECURITY_ATTRIBUTES lpFileMappingAttributes,    // 安全描述符,填写 NULL             
  DWORD flProtect,                                   // 映射对象保护属性
  DWORD dwMaximumSizeHigh,                           // 文件映射的最大长度的高32位
  DWORD dwMaximumSizeLow,                            // 文件映射的最大长度的低32位
  LPCTSTR lpName                                     // 文件映射对象名称
);

2、MapViewOfFile // 将内存映射文件映射到进程的虚拟地址中



LPVOID MapViewOfFile(
  HANDLE hFileMappingObject,  // CreateFileMapping()返回的文件映像对象句柄
  DWORD dwDesiredAccess,      // 数据的访问方式
  DWORD dwFileOffsetHigh,     // 文件映射起始偏移的高32位
  DWORD dwFileOffsetLow,      // 文件映射起始偏移的低32位
  DWORD dwNumberOfBytesToMap  // 文件中要映射的字节数,为0表示映射整个文件映射对象
);

3、OpenFileMapping // 在接收进程中打开对应的内存映射对象

// 如果函数成功,返回值是指定文件映射对象的打开句柄。失败返回 NULL。



HANDLE OpenFileMapping(
  DWORD dwDesiredAccess,  // 数据的访问方式
  BOOL bInheritHandle,    // 是否继承句柄
  LPCTSTR lpName          // 要打开的文件映射对象名称
);


三、使用步骤

  • 使用CreateFileMapping创建一个内存映射文件内核对象,告诉操作系统内存映射文件需要的物理内存大小,这个步骤决定了内存映射文件的用途――究竟是为磁盘上的文件建立内存映射还是为多个进程共享数据建立共享内存。或者使用OpenFileMapping打开映射文件内核对象。
  • 映射文件映射对象的全部或一部分到进程的地址空间,可以认为该操作是为文件中的内容分配线型地址空间,并将线型地址和文件内容对应起来,完成该操作的函数是MapViewOfFile。

四、使用内存映射文件读文件的具体过程

  1. 调用CreateFile函数打开想要映射的文件,得到文件句柄hFile。
  2. 调用CreateFileMapping函数,并传入文件句柄hFile,为该文件创建一个内存映射内核对象,得到内存映射文件的句柄hMap。
  3. 调用MapViewOfFile函数映射整个文件或一部分到进程的虚拟地址空间。该函数返回文件映射到内存后的起始地址。使用指向这个地址的指针就可以读取文件的内容了。
  4. 调用UnmapViewOfFile函数来解除文件映射。
  5. 调用CloseHandle函数关闭文件对象,必须传入内存映射文件句柄hMap
  6. 调用CloseHandle函数关闭文件对象,必须传入文件句柄hFile。
     

五、示例——读超大文件

约1G身份证文件的读取(含中文、英文、特殊符号)


int main(int argc, char** argv) {

	clock_t start, finish;
	strcpy(path, argv[1]);//输入的文件名
	ios::sync_with_stdio(0);
	cin.tie(0);
    //开始计时
	start = clock();
	HANDLE hFile = CreateFile(fn_convertCharArrayToLPCWSTR(path),
		GENERIC_READ | GENERIC_WRITE,
		FILE_SHARE_READ,
		NULL,
		OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL,
		NULL);
	if (hFile == INVALID_HANDLE_VALUE)
	{
		cout << " CreateFile fail" << endl;
		return -1;
	}

	//创建一个文件映射内核对象
	HANDLE hFileMap = CreateFileMapping(hFile,
		NULL,
		PAGE_READWRITE,
		NULL,
		NULL,
		L"Resource");
	if (hFileMap == NULL)
	{
		cout << "CreateFileMapping fail" << endl;
		return -1;
	}

	//将文件数据映射到进程的地址空间
	char* pMapData = (char*)MapViewOfFile(hFileMap,
		FILE_MAP_ALL_ACCESS,
		NULL,
		NULL,
		NULL);
	if (pMapData == NULL)
	{
		cout << " MapViewOfFile fail" << endl;
		return -1;
	}

	//读取数据
	char* pBuf = pMapData;

	finish = clock();
	//cout << "Read 1g ID file time :" << float(finish - start) << "  ms " << endl;
	printf("读取1G身份证文件的运行时间:%f毫秒\n", (float)(finish - start));
    //计时结束
}
    //撤销文件视图
	UnmapViewOfFile(pBuf);
	//关闭映射文件句柄
	CloseHandle(hFile);
	CloseHandle(hFileMap);

六、运行结果

cmd运行程序读取1G大小的身份证文件,结果为1ms

C++ CreateFileMapping 内存映射实现快速读取文件

 参考文献:

CreateFileMapping , OpenFileMapping, MapViewOfFile, UnmapViewOfFile 和 FlushViewOfFile_老白436196571的博客-CSDN博客_createfilemapping


 文章来源地址https://www.toymoban.com/news/detail-405481.html

到了这里,关于C++ CreateFileMapping 内存映射实现快速读取文件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 浅聊一下 C#程序的 内存映射文件 玩法

    前段时间训练营里有朋友问 内存映射文件 是怎么玩的?说实话这东西理论我相信很多朋友都知道,就是将文件映射到进程的虚拟地址,说起来很容易,那如何让大家眼见为实呢?可能会难倒很多人,所以这篇我以自己的认知尝试让大家眼见为实。 在任何讨论之前,内存文件

    2024年02月08日
    浏览(25)
  • Java+GeoTools(开源的Java GIS工具包)快速入门-实现读取shp文件并显示

    GeoTools 是一个开源的 Java GIS 工具包,可利用它来开发符合标准的地理信息系统。 GeoTools 提供了 OGC (Open Geospatial Consortium) 规范的一个实现来作为他们的开发。 官网地址: GeoTools The Open Source Java GIS Toolkit — GeoTools 参考其quick start教程,实现集成到maven项目中并运行示例代码。

    2024年02月08日
    浏览(34)
  • ffmpeg 子进程从内存读取文件、提取图片到内存

    除了网络、文件io,由python或java或go或c等语言开启的 ffmpeg子进程 还支持pipe,可以从stdin读入数据,输出转化后的图像到stdout。无需编译 ffmpeg,直接调用 ffmpeg.exe不香么! “从内存读”可用于边下载边转码,节省硬盘寿命。 “提取到内存”可用于服务端生成缩小的预览图,然

    2024年02月11日
    浏览(30)
  • Windows本地快速搭建SFTP服务共享文件 - 外网访问【端口映射】

    转载自cpolar极点云的文章:如何在内网搭建SFTP服务器,并发布到公网可访问 下载地址:http://www.freesshd.com/?ctt=download 选择freeFTPD.exe下载 下载后,点击安装 安装之后,它会提示是否启动后台服务,Yes 安装后,点击开始菜单– freeFTPd, 注意 :这里要点击鼠标右键, 以管理员权

    2024年02月06日
    浏览(28)
  • 从内核世界透视 mmap 内存映射的本质(源码实现篇)

    本文基于内核 5.4 版本源码讨论 通过上篇文章 《从内核世界透视 mmap 内存映射的本质(原理篇)》的介绍,我们现在已经非常清楚了 mmap 背后的映射原理以及它的使用方法,其核心就是在进程虚拟内存空间中分配一段虚拟内存出来,然后将这段虚拟内存与磁盘文件映射起来,

    2024年02月08日
    浏览(45)
  • DS/ML:模型全流程优化之系统优化—替代Pandas库的大数据高效处理技术优化集合如HDF5技术(压缩文件)+vaex库(内存映射)+dask库(集群技术)替代pandas的各自骚操作实现代码

    DS/ML:模型全流程优化之系统优化—替代Pandas库的大数据高效处理技术优化集合如HDF5技术(压缩文件)+vaex库(内存映射)+dask库(集群技术)替代pandas的各自骚操作实现代码 目录

    2024年02月09日
    浏览(34)
  • Linux的常用命令和配置Host文件对虚拟机IP快速映射

    基础四大命令 ls命令: ls -alh 参数 -a : 展示出隐藏文件 .开头就是隐藏文件 参数 -l : 以详细信息展示文件 我常用ll 代替 ls-l的命令 参数 -h : 显示文件大小,但是搭配方式是 ls -lh cd命令: 用来切换路径cd 后面加上路径 example: cd / 进入根目录 pwd命令: 查看当前路径 ifconfig命令: 查看

    2024年04月11日
    浏览(31)
  • IDEA好用插件:MybatisX快速生成接口实体类mapper.xml映射文件

    目录  1、在Idea中找到下载插件,Install,重启Idea  2、一个测试java文件,里面有com包  3、在Idea中添加数据库 --------以Oracle数据库为例  4、快速生成entity-service-mapper方法  5、查看生成的代码  6、自动生成(增删查改)在TestMapper中快速编写代码 1、在Idea中找到下载插件,Ins

    2024年02月02日
    浏览(39)
  • Java读取600万行的txt文件,内存溢出解决方案

    可能造成内存溢出的原因: 一次性把txt文件读取到内存 频繁的new对象 实体类 可以使用对象池解决频繁new对象的问题 解决一次性把文件读取到内存: 可以使用文件流方式,使用java.util.Scanner类扫描文件的内容,一行一行连续地读取

    2024年04月14日
    浏览(32)
  • 快速检测 GlassFish 任意文件读取漏洞的 Python 脚本

    部分数据来源: ChatGPT 引言         当下,互联网安全问题正愈发严重,黑客利用各种漏洞进行攻击的频率也在持续增加。在2015年10月,一位名为“路人甲”的安全研究员在乌云上公开了一个名为“应用服务器glassfish存在通用任意文件读取漏洞”的漏洞(编号:wooyun-201

    2024年02月07日
    浏览(24)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包