内存映射处理大文件并实现逆序输出

上一篇介绍了一种常见的文件处理方法(可优化为:分次读取文件,但要满足根据行号能快速索引该行内容时会遇到麻烦),所以此片我将介绍另一种更高效,实用,并对本进程的内存空间地址消耗小的方法!


一. 预备知识

1). Windows编程处理文件的相关接口:

A)CreateFile();

B)ReadFile();

c)WriteFile();

d)CloseHandle();

2). 文件映射相关接口:

A)  CreateFileMapping()

B)MapFIleOfView()

C)OpenFileMapping()

D)CloseHandle()

3)注:

由于以上接口MSDN以及网上的牛人们已经给了详细的介绍了,这里我只累叙 一下MapViewOfFile()第四个参数 DWORD dwFileOffsetLow;

此偏移量必须64k对齐,可能是由于便于内存管理得快速访问,才做此限定,如下代码:

    LARGE_INTEGER liOffset = {};liOffset.QuadPart = lpLineInfo->liHeadCharOffset.QuadPart & (~MemmoryHex_64k);DWORD DValue = DWORD(lpLineInfo->liHeadCharOffset.QuadPart - liOffset.QuadPart);char *lpHeadSrc = (char*)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, liOffset.HighPart, liOffset.LowPart, (DValue + lpLineInfo->LineCount));

二.思想

1) 在处理文件过程中,我们一般采用的方法是分块(如每次512k)读取文件数据进行处理,这样做的目的如下

A)申请小块内存速度快

B)可以不用New动态创建存数据的Buffer,而是直接可以用栈存储次Buffer,降低内存泄漏的风险

C)若一次申请一块较大的地址空间(>512M),那你还让其他线程工作吗?一个进程中的多个线程是共用同一块地址空间的!

对于B:有朋友会说,那可以将进程中允许访问的栈空间调大(1G),但这样是有风险的,比如你在编写递归代码时出错,可能导致死循环,由于堆设得过大,导致要许久才会导致栈溢出,增加我们调式bug得难度!而当栈的空间地址范围较小时,函数调用栈很快就会溢出,Buf易复现,就便于修改了!


2)当文件大小在允许访问内(我的机器<24G),将文件内容映射到内存上,对文件的访问速率相当于内存的读取率;

A)注:我的公司开发机:Win7 64位,16G运行内存,15G虚拟内存)

B)由于映射的内存块可以被本机的其他进程访问,所以我们通常也称之为共享内存!


3)每次映射小块文件数据到次进程的地址空间上,进行处理(与上篇中处理方式一样)

        DWORD RelMapMemorySize = DWORD((liTotalFileSize.QuadPart - liHandleFileSize.QuadPart + DValue > EachMapMemorySzie) ? EachMapMemorySzie : (liTotalFileSize.QuadPart - liHandleFileSize.QuadPart + DValue));lpHeadSrc = (char*)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, liOffset.HighPart, liOffset.LowPart, RelMapMemorySize);

4)根据行号索引该行内容,相当于随机访问数组的速率

相交与上篇,此篇存储每一行信息的数据结构有所改变,如下

    typedef struct LINE_INFO{LARGE_INTEGER   liHeadCharOffset;INT32           LineCount;}LINE_INFO;

A)我们根据liHeadCharOffset算出映射时候的偏移量!

B)注意:我们必须保证此低字节的偏移量必须64K对其,所以这里必须先对liHeadCharOffset进行处理!

a)映射偏移量首先对此值取商

    LARGE_INTEGER liOffset = {};liOffset.QuadPart = lpLineInfo->liHeadCharOffset.QuadPart & (~MemmoryHex_64k);DWORD DValue = DWORD(lpLineInfo->liHeadCharOffset.QuadPart - liOffset.QuadPart);

b)处理时再加上我们做商时舍弃的差值

    char *lpHeadSrc = (char*)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, liOffset.HighPart, liOffset.LowPart, (DValue + lpLineInfo->LineCount));if (NULL == lpHeadSrc){m_lpHLog->TraceLog("Error(%s.%d): MapViewOfFile Failed!\r\n", __FUNCTION__, __LINE__);return FALSE;}char *lpHead = lpHeadSrc + DValue;

	5)关于倒叙写文件相信聪明的朋友也能按照上述方案分块映射分块写了,就不在累叙了

	6)其余处理之处应与上一篇类似(实际已近不记得了,因为此代码是上个月初写的,我上一篇的代码是这个月初写的。。。),也不过多介绍了!

三. 最后上一下运行图
	注:本机是在是找不到大的文本文件,当明显速度比上一篇中的处理速度快,且我在开发机上测试时,Release模式下(不包含最后逆序写文件)文件处理速度达到100M/s
这数据也许不准,因为Windows操作系统对开机第一次读取文件比以后读取文件速率慢很多,据说与什么预读和磁盘命中率有关,总之就是比文件映射处理文件速率比较快!
	

	此文件80M左右,Debug模式下,给我的感觉基本是1s左右!(我的本本是5年前卖的)
	最后看了下时间,如右:2016/08/05 22:40:43.407   Time is 1357(单位是ms)

四)如果对源码有兴趣得朋友可以点击这里下载源码!
 
五)如发现我上述观点有错误的地方,希望朋友不啬指出,方便大家共同提升,谢谢!
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/447642.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决: tar: Removing leading `/‘ from member names

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. 我的情况 。 使用绝对路径 执行 tar 命令&#xff1a; tar -zcvf clientOne.tar /root/jiangyu/projects/springCloud/clientOne/s…

ObjectArx创建指定块

ObjectArx创建自定义块 一. 目的仿照AutoCad的Block命令&#xff0c;实现简版创建块功能!二. 开发环境Win7操作系统&#xff0c;AutoCad2012&#xff0c; VS2008, ObjectArx_SDK_2012三. 相关函数简介1) int acedSSGet (const ACHAR *str, const void *pt1,const void *pt2…

解决:Dockerfile 中执行 tar 命令始终报错:tar: /xx/xx: Cannot stat: No such file or directory tar: Exiting with

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. docker 执行 build &#xff0c; dockerfile 中有一行命令&#xff1a; RUN tar -zcvP -f clientOne.tar /root/jiangyu/projects/…

ObjectArx创建自定义实体

ObjectArx创建自定义实体 一。目的在ObjectArx中已经有了许多实体&#xff0c;如AcDbLine,AcDbCircle,AcDbArc等&#xff0c;但在用户使用Cad时&#xff0c;会有一些对他们来讲常用的“实体“&#xff0c;如一扇门&#xff0c;如果我们能提供一个“门实体“&#xff0c;让用户能…

开车人千金难买的知识!(组图)

开车的人千金难买的知识: 前言&#xff1a; 一、 发动机是怎样被您自己开坏的 二、 变速箱是怎样被您自己开坏的 三、 排水口&#xff08;很重要您肯定不知道的&#xff09; 四、 离合 五、 水箱 六、 方向助力 七、 空调 八、底盘 九、爱车是如何被自己撞坏的&#x…

如何在 IDEA 启动多个 Spring Boot 工程实例

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 一个工程启动多个实例&#xff0c;分别占用不同的端口。 step 1 在IDEA上点击Application右边的下三角 ,弹出选项后&#xff0c;点击Ed…

重启 docker 服务、Docker 重启

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. 我的情况 &#xff1a;重启阿里云 ECS 服务器后&#xff0c;一切服务都停止了。 重启 XXX 服务通用命令&#xff1a;service xxx re…

linux 查看 CPU 使用率

1&#xff1a;top 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 top -bn 1 -i -c top命令可以看到总体的系统运行状态和cpu使用效率 %us: 表示用户空间程序的cpu使用效率 %sy:表示…

解决: service endpoint with name xxx already exists ( docker 已删除的容器却依旧存在)

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. 启动服务报错如题 确认 我已经 docker rm -f XXX 了。也确认 各个容器端口并不重复。 重新启动容器服务依旧报错&#xff1a; 粗…

解决:There was an unexpected error (type=Internal Server Error,..). No instances available for XXX

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1.我的情况&#xff1a; 实践 springCloud , 启动了注册中心 eureka、也启动了 服务生产者、服务消费者。 eureka 端口&#xff1a; 1…

springCloud - 第3篇 - 消费者调用服务 ( RestTemplate + Ribbon )

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 一、新建 ribbon 工程&#xff1a; 1. file - new - module 2. spring Initializr - module SDK 选择自己的 JDK &#xff0c;其余的可…

延长汽车使用寿命,抛弃六大用车坏习惯

汽车使用越来越普及&#xff0c;因为用车习惯问题导致汽车寿命减短&#xff0c;因错误用车习惯导致伤车、损车的例子比比皆是。而用车习惯得当与否&#xff0c;直接关系到汽车的使用寿命。例如发动机&#xff0c;如果保养得当&#xff0c;开50万~60万公里都没问题。汽车使用越来…

解决:Whitelabel Error Page This application has no explicit mapping for /error...UnknownHostException

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. 我的情况 &#xff1a; springcloud 实践&#xff0c;启动 ribbon 工程后&#xff0c;请求接口报错&#xff1a; Whitelabel Error…

springCloud - 第4篇 - 消费者调用服务 ( Feign )

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 一、新建 ribbon 工程&#xff1a; 1. file - new - module 2. spring Initializr - module SDK 选择自己的 JDK &#xff0c;其余的可…

使用 idea 创建第一个 springboot 项目

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 如今springboot越来越火&#xff0c;越来越多的公司选择使用springboot作为项目的开发框架&#xff0c;其设计目的就是用来简化spring项…

坚持步行的惊人效果,网上被疯狂转载!

俗话说&#xff0c;人老腿先老。由于人体2/3的肌肉集中在下半身&#xff0c;所以六十多岁的人可以有年轻人七成的握力和臂力&#xff0c;但下半身力量却只剩下四成。不过&#xff0c;大家也不必担心。最近&#xff0c;包括以色列、美国在内的科学家们发现&#xff0c;温和地健步…

springCloud - 第5篇 - 断路器 Hystrix ( Feign 、Ribbon )

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 一、为什么要有熔断 在微服务架构中&#xff0c;根据业务来拆分成一个个的服务&#xff0c;服务与服务之间可以相互调用&#xff08;RP…

springCloud - 第6篇 - 网关的实现:ZUUL

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 在Spring Cloud 微服务系统中&#xff0c;一种常见的负载均衡方式是&#xff0c;客户端的请求首先经过负载均衡&#xff08;zuul、Ngnix…

亚特兰大峰会精彩看点:软件吞噬世界,OpenStack是变革核心

摘要&#xff1a;5月12日早9点&#xff0c;OpenStack Atlanta峰会在超过90家赞助厂商和4500名参会者的陪伴下拉开了序幕。Jonathan Bryce特别提出了Superuser和Marketplace两个新概念&#xff0c;软件正在吞噬整个世界&#xff0c;OpenStack是这场变革的核心。 第一天精彩看点…

解决: Gitee 自已提交的代码提交人头像为他人、码云上独自开发的项目显示为 2 个开发者

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. 我的情况 &#xff1a; 项目一直只有我一个开发者&#xff0c;却莫名的出来了一个完全不认识的开发者&#xff0c;我新建后 push 的…