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

一. 起因

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


二. 方案

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,一经查实,立即删除!

相关文章

pom.xml 配置之:snapshot 快照库和 release发布库 的区别

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1、如果在发布时使用 mvn deploy -P release 的命令&#xff0c;那么会自动使用0.1作为发布版本&#xff0c;那么根据 maven 处理 snaps…

米饭凉一凉再吃会更加地健康

米饭&#xff0c;是人们日常饮食中的主角之一;一味米饭&#xff0c;与五味调配&#xff0c;几乎可以供给全身所需营养。大米性平、味甘;有补中益气、健脾养胃、益精强志、和五脏、通血脉、聪耳明目、止烦、止渴、止泻的功效。 人们往往认为米饭应该趁热的时候吃。 但是用电饭煲…

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

上一篇介绍了一种常见的文件处理方法(可优化为&#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…

告诉你中国著名的40个四大是什么?

中国著名的40个四大 一、四大江南才子&#xff1a;唐伯虎、文征明、祝枝山、徐祯卿&#xff1b; 二、四大才女&#xff1a;蔡文姬、班昭&#xff08;又说上官婉儿&#xff09;、卓文君、李清照&#xff1b; 三、四大名著&#xff1a;《三国演义》、《西游记》、《水浒传》、《…

解决: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…

安装micro/go-micro

创建文件夹&#xff0c;拉取相关包 mkdir golang.org cd golang.org mkdir x cd x git clone https://github.com/golang/net.git git clone https://github.com/golang/crypto.git git clone https://github.com/golang/sys.git git clone https://github.com/golang/…

刹车八个技巧 教你踩得又稳又好

驾车加速行驶&#xff0c;这是谁都可以做到的。但是如果我们不能够正确地操作刹车&#xff0c;汽车有可能在一瞬间变成事故的凶器&#xff0c;因此&#xff0c;也许我们可以说刹车技术是驾驶汽车的境界之一。以下为大家列举八种刹车技巧&#xff0c;如果全部掌握的话&#xff0…

springcloud 注解 @EnableDiscoveryClient 与 @EnableEurekaClient 的区别

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 在使用 Spring Cloud feign 服务发现时提到两种注解&#xff1a; EnableDiscoveryClient、EnableEurekaClient 。 spring cloud 中 disc…

开车路上怎样赶走瞌睡虫?网友支招如何防路困

春困秋乏&#xff0c;秋天时不时来个哈欠打个盹也是人之常情&#xff0c;可是如果您正在路上开车可就是危险之极的事情了&#xff01;要知道&#xff0c;这在路上开快车不是最危险的&#xff0c;最危险的是走神&#xff0c;而打瞌睡更是要命的&#xff01;可这打瞌睡是身体疲乏…

重启 docker 服务、Docker 重启

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

25岁肥胖!美研究:晚年恐出现病态肥胖

如果您现在刚好25岁&#xff0c;最好注意一下现在的体重&#xff0c;因为美国纽约大学最新研究发现&#xff0c;如果在25岁这个年龄&#xff0c;您的体重是超重的&#xff0c;10年后肥胖的机率会比较高&#xff0c;男生恐怕高到23.1%&#xff0c;女生高到46.9%&#xff0c;而年…

linux 查看 CPU 使用率

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

新研究:长寿又健康的秘诀

最近对南加州一个退休社区&#xff0c;成千上万90岁以上者的一项具有里程碑意义的研究&#xff0c;指出了长寿的可能因素。吸烟致使寿命缩短&#xff0c;运动使人活得更长。即使从事非运动的方式&#xff0c;保持活跃的生活&#xff0c;也会延长寿命。肥胖不好&#xff0c;但过…

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

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

广州驾考科目三电子考16日全面启动

驾考科目三人工考“短暂复出” 增加13天过渡期&#xff0c;16日全面启动电子考 南方日报讯(记者/赵琦玉 通讯员/交宣)昨日&#xff0c;广州驾考科目三电子考试新政在实施2天之后&#xff0c;陡然“刹车”进行调整。从昨日起至本月15日共13天的过渡期内&#xff0c;已预约科目三…