內存映射處理大文件并實現逆序輸出

上一篇介紹了一種常見的文件處理方法(可優化為:分次讀取文件,但要滿足根據行號能快速索引該行內容時會遇到麻煩),所以此片我將介紹另一種更高效,實用,并對本進程的內存空間地址消耗小的方法!


一. 預備知識

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.pswp.cn/news/447642.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/447642.shtml
英文地址,請注明出處:http://en.pswp.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…

告訴你中國著名的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;已預約科目三…

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

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1.我的情況&#xff1a; 實踐 springCloud , 啟動了注冊中心 eureka、也啟動了 服務生產者、服務消費者。 eureka 端口&#xff1a; 1…

延長汽車壽命的6個良好習慣

怎樣最大程度的使用你的汽車涉及到許多東西&#xff0c;比如保養維護&#xff0c;還有良好的駕駛習慣。很多人對正確的維護保養對延長汽車壽命的重要性已很了解&#xff0c;所以我們這里集中談一談什么是良好的駕車習慣。駕車習慣和方式決定了汽車的預期壽命&#xff0c;換另一…

springCloud - 第3篇 - 消費者調用服務 ( RestTemplate + Ribbon )

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 一、新建 ribbon 工程&#xff1a; 1. file - new - module 2. spring Initializr - module SDK 選擇自己的 JDK &#xff0c;其余的可…