文件逆序输出及根据行号索取该行内容

一. 起因

年初,一位同学提取了如何实现倒叙输出文件,根据行号索引该行内容,我思考了一下,得出以下二种方案!


二. 方案

1)方案1:(此方案局限性较大,并且耗内存)

准备一个结构体,用来存储每行起始字符的地址以及该行字符的个数(带换行符),遍历此文件,将文件内容存放到堆中(耗内存的原因),在遍历过程中将每行的起始地址与该行大小分别存在准备好的结构体中!最后,倒叙读取结构体的内容,取得相应的行内容,写入文件,即可完成文件逆序输出,并且也可以根据行号索引来获取该行内容

2)方案2:(不耗内存,速率更快)

基本思想与方案一异曲同工,只不过用到文件映射(CreateFileMapping,MapViewOfFile),首先一次性将文件映射到本进程外的内存中,然后分块读取该共享内存的内容,此种方法及源码将在下片中详细介绍,这里就不做过多的叙述了!



三. 详细论述方案一的优缺点

1)优点

A. 只需一次遍历即可实现倒叙输出与按行号索引该行内容(只想到此点)

2)缺点

A. 由于在32为系统中,单进程我们能用到的地址空间仅有大约2G(进程中总地址空间4G, 除去空指针赋值区,64K禁入区,内核模式分区外,可用约2G),所以我们想要申请堆大小被限制在2G内,,加上进程中其他耗费的地址空间,故此方案局限性很大,仅能处理小文件(1G以内)!

B. 在编码过程中一次分配1G的内存空间是非常的不合理的!

C.效率低(一般情况下: 用户申请一段连续的大的内存块比将申请多段小的内存快耗时长)

如:申请一块60M的内存来处理数据比10次,每次处理10M来处理数据的速率低(方案2可以证实)


四.

是不是看到以上致命缺点对后面的内容没有兴趣了,其实我也是,由于不用注重速率了,所以我在此例中用到了新学的知识,oost::Shared_Ptr与Vector的结合使用,有兴趣的朋友可以看下,或者之处我使用之处的不足!



五.  实现方案代码详解

1)数据结构准备

    typedef struct LINE_INFO{char    *lpLineHead;        INT32   LineSize;           // contain '\n'}LINE_INFO;<span style="white-space:pre">	</span>

    typedef struct LOAD_FILE_PARAM{WCHAR   wcsFilePathName[MAX_PATH];<span style="white-space:pre">	</span> HWND    hWnd;<span style="white-space:pre">				</span> INT32   MessageID;INT32   Param[4];}LOAD_FILE_PARAM;


2) 成员变量

<pre name="code" class="cpp">
char *m_lpFileData; vector<boost::shared_ptr<LINE_INFO>> m_LineInfoVector; LARGE_INTEGER m_liFileSize; HLog *m_lpHLog; WCHAR m_wcsReverseFilePath[MAX_PATH];

 
3)供用户使用的接口 

    LOAD_FILE_PARAM     m_LoadFileParam;BOOL AnalysisFile(LOAD_FILE_PARAM *lpLoadFileParam);                // asynBOOL CallBack_AnalysisFile(LOAD_FILE_PARAM *lpLoadFileParam);       // synBOOL ReverseFileData();                                             // asynBOOL CallBack_ReverseFileData();                                    // synBOOL GetLineInfoByLineIndex(INT32 LineIndex, char csLineBuffer[], INT32 MaxBufferSize);UINT64 GetLineCount();

4)具体实现遍历文件代码

BOOL ReverseFile::CallBack_AnalysisFile(LOAD_FILE_PARAM *lpLoadFileParam)
{DWORD tBeginTime = GetTickCount();#pragma region Check Paramif (NULL == lpLoadFileParam || 0 == wcslen(lpLoadFileParam->wcsFilePathName)){m_lpHLog->TraceLog("Error(%s.%d): Param Illegal!\r\n", __FUNCTION__, __LINE__);return FALSE;}if (NULL == lpLoadFileParam->hWnd || lpLoadFileParam->MessageID < WM_USER){m_lpHLog->TraceLog("Waring(%s.%d): hWnd or MessageID Illegal!\r\n", __FUNCTION__, __LINE__);}WCHAR wcsPathName[MAX_PATH] = {};_snwprintf_s(wcsPathName, _TRUNCATE, lpLoadFileParam->wcsFilePathName);wcsrchr(wcsPathName, _T('\\'))[1] = _T('\0');_snwprintf_s(m_wcsReverseFilePath, _TRUNCATE, _T("%sReverse.log"), wcsPathName);
#pragma endregionHANDLE hFile = CreateFile(lpLoadFileParam->wcsFilePathName, GENERIC_READ, FILE_SHARE_READ, NULL,OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);if (INVALID_HANDLE_VALUE == hFile){m_lpHLog->TraceLog("Error(%s.%d): CreateFile Failed!\r\n", __FUNCTION__, __LINE__);return FALSE;}GetFileSizeEx(hFile, &m_liFileSize);if (m_liFileSize.QuadPart > MaxFileSize)          // Over 1G{m_lpHLog->TraceLog("Error(%s.%d): File too Big!\r\n", __FUNCTION__, __LINE__);return FALSE;}m_lpFileData = new char[m_liFileSize.QuadPart];     // low?DWORD RelRead = 0;ReadFile(hFile, m_lpFileData, (DWORD)m_liFileSize.QuadPart, &RelRead, NULL);    // low?      char *lpHead = m_lpFileData;char *lpTail = m_lpFileData + m_liFileSize.QuadPart;while(lpHead < lpTail){char *lpErgodic = lpHead;while (*lpErgodic != 0x0A && lpErgodic < lpTail){lpErgodic++;}if (lpErgodic > lpTail && *lpErgodic != 0x0A){break;}if (*lpErgodic == 0x0A){lpErgodic++;}INT32 LineSize = lpErgodic - lpHead;boost::shared_ptr<LINE_INFO> lpLineInfo(new LINE_INFO());lpLineInfo->lpLineHead = lpHead;lpLineInfo->LineSize   = LineSize;m_LineInfoVector.push_back(lpLineInfo);lpHead = lpErgodic;INT32 Progress = INT32(double(lpHead - m_lpFileData) * 100 / m_liFileSize.QuadPart);::PostMessageA(lpLoadFileParam->hWnd, lpLoadFileParam->MessageID, 0, (LPARAM)Progress);         // Low}DWORD tEndTime = GetTickCount();m_lpHLog->TraceLog("Time is %d\r\n", tEndTime - tBeginTime);return TRUE;}

六.效果展示

(爱好刀塔的朋友(*^__^*) 嘻嘻)


七. 源码地址:http://download.csdn.net/detail/u012158162/9594174

注: 1)由于此源码只是一个范例,故中存在一些Bug,如没有考虑到重入问题,以及存在不合理的强转,都是可以修改及优化的地方!

2)如没有配置Boost库的朋友可以将用到Boost库智能指针的地方用常用指针替换,注意内存释放,防止泄漏!

3)如没有安装VLD的朋友,将头文件件中包含(#include “vld.h”)注释掉即可!

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

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

相关文章

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

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

解决: 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是这场变革的核心。 第一天精彩看点…