摘 要:目前,隨著計算機在各個產(chǎn)業(yè)部門的逐漸普及、計算機運算能力的逐步提高以及各種新型需求的誕生,對文件存儲以及訪問的需求也隨之升高,人們已經(jīng)不能滿足于基于兆級的數(shù)據(jù)文件的訪問,更大的數(shù)據(jù)文件的訪問和支持能力對開發(fā)人員提出了更高的要求,但是,受計算機硬件條件、系統(tǒng)軟件的版本以及軟件開發(fā)版本的約束,我們并不能大刀闊斧的對軟件進行徹底修改,否則會對軟件的兼容性造成非常嚴重的危害,因此我們需要針對不同情況來分別對各種大型數(shù)據(jù)進行遍歷,從而保證軟件在不同配置的計算機上能夠順利運行。
關鍵詞:新型需求 徹底修改 遍歷
中圖分類號:TP3 文獻標識碼:A 文章編號:1672-3791(2013)01(b)-0024-01
在石油及礦產(chǎn)勘探領域,經(jīng)常使用不同方式對地層進行探測,隨著探測手段日益增強,衍生出的數(shù)據(jù)量也越來越大,從早期的幾十兆到現(xiàn)在的幾個G的級別,不僅對計算機的要求日益提高,同時對軟件開發(fā)人員也提出了更高的要求:開發(fā)人員要花費大量精力來優(yōu)化內(nèi)存以及CPU的使用,并且還要針對一些數(shù)據(jù)結構不能操作大型數(shù)據(jù)進行擴展。本文針對某油田測井數(shù)據(jù)格式的大數(shù)據(jù)量文件的操作,分別闡述了幾種不同情況的處理方法。
本程序是基于VC6.0開發(fā)的,其運行環(huán)境為32位Windows系統(tǒng)。
1 修改數(shù)據(jù)描述格式
首先,我們需要面對的是數(shù)據(jù)格式不能滿足需求的問題,對所有標識文件數(shù)據(jù)塊大小的字段進行類型的修改,原有的代碼中沒有考慮到大數(shù)據(jù)量的可能性,對數(shù)據(jù)塊大小的描述都是采用的整型int型或長整型long格式,由于采用的是有符號整型,所以其只能標識-2147483648~2147483648的文件塊大小,這對于一般的線性數(shù)據(jù)塊大小是足夠的,但是對于大范圍的波列數(shù)據(jù)以及矩陣類型數(shù)據(jù)的描述就捉襟見肘了。本程序采用了一種叫做ULONGLONG的據(jù)格式,該格式為無符號64位數(shù)據(jù)格式,理論上可以達到0~18446744073709551616的存儲長度,這樣的話對于任意可能存在的數(shù)據(jù)長度,該格式都是足夠描述的。
2 采用內(nèi)存映射
其次,我們采用了內(nèi)存映射方式來克服大塊內(nèi)存的分配問題:對于內(nèi)存分配,我們的數(shù)據(jù)格式是連續(xù)存儲的,對于每塊特定的數(shù)據(jù)內(nèi)容,其讀取和寫入也必須是連續(xù)的,因此在處理大數(shù)據(jù)量的數(shù)據(jù)操作時,常常會遇到需要分配巨大內(nèi)存空間的問題,而對于32位操作系統(tǒng),系統(tǒng)本身可識別的內(nèi)存僅為4G,除掉其他程序耗費掉的內(nèi)存,系統(tǒng)在分配大內(nèi)存空間上就顯得力不從心,即使能夠分配成功,其程序的執(zhí)行效率也會變得極低。除此之外,在多次處理大數(shù)據(jù)量的數(shù)據(jù)過程中,還發(fā)現(xiàn)了一個特殊的現(xiàn)象,即Windows系統(tǒng)中的內(nèi)存碎片是影響內(nèi)存分配的,我們在分配大數(shù)據(jù)量的內(nèi)存前,如果已經(jīng)有一些進程運行,那么可能會把整個的內(nèi)存空間打破,如果這些破碎的內(nèi)存任何一塊不足以分配我們所需的內(nèi)存空間,則系統(tǒng)無法分配內(nèi)存,從而導致內(nèi)存分配失敗,為此我們采用了內(nèi)存映射的手段來克服大數(shù)據(jù)量數(shù)據(jù)的操作難題,過程如下。
(1)首先我們把需要操作的數(shù)據(jù)文件File1進行一個復制操作,生成一個新的臨時文件File1Copy。
(2)然后聲明一個內(nèi)存映射對象CMem MapFile mmf。
(3)聲明一個指針,用來指示共享內(nèi)存中的文件位置LPVOID pDataVoid。
(4)用CMemMapFile對象打開臨時文件if(mmf.MapFile(tempName,TRUE,F(xiàn)ILE_SHARE_READ))
{pDataVoid=mmf.Open();}
(5)使用pDataVoid指針可以任意讀取數(shù)據(jù),并且可以把難以分配的大塊數(shù)據(jù)空間進行分割操作,從而獲得較好的運行效率。
(6)數(shù)據(jù)操作完畢,刪除臨時文件,釋放mmf.UnMap()。
通過使用內(nèi)存映射,我們有效的規(guī)避的大塊內(nèi)存分配的瓶頸,同時可以使得讀取和寫入文件更加靈活。
3 采用CFile64遍歷文件
目前巨大文件越來越多,對于本軟件所需要操作的數(shù)據(jù)文件,由于大量的波列和矩陣數(shù)據(jù)的加入,突破G的文件也是越來越多,甚至有很多已經(jīng)達到了MFC中CFile類可操作數(shù)據(jù)的上限4GB,原因是CFile類中使用了32位整型來處理文件,從而導致了最大處理能力僅為4GB,為了能夠處理這種巨大的文件,我們采用了一種CFile64的文件讀取類,該類繼承于CFile,對其中的整型數(shù)據(jù)int轉換為ULONGLONG格式,并且對其中的Seek、Read、Write函數(shù)進行了重載,從而使得CFile64理論上能夠支持18000000000GB的文件操作,這顯然完全能夠勝任我們的需求,對于CFile64類的使用與原有的MFC中的標準CFile類有些不同,主要集中在數(shù)據(jù)的遍歷以及讀取寫入函數(shù)上。CFile64打開及讀取數(shù)據(jù)代碼如下:
CFile64 m_file;
m_file.Open(fileName,GENERIC_WRITE|GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, OPEN_EXISTING)
POSITION pos;
m_file.Seek(pos,CFile64::begin,1);
m_file.Read(&pos,sizeof(long));
4 結論
通過使用ULONGLONG格式,我們首先解決了在編程過程中整形變量無法對巨大數(shù)據(jù)塊大小描述的問題;其次我們通過內(nèi)存映射,有效的解決了非連續(xù)內(nèi)存塊無法分配的問題和大內(nèi)存耗用情況下程序運行效率的問題;使用CFile64類,解決了原有CFile類不能操作4GB以上文件的弊端,至此,我們對VC6.0環(huán)境下基于32位系統(tǒng)操作大文件的能力進行了有效的擴充,開發(fā)出的程序不僅能夠處理4GB以上的大文件,同時對內(nèi)存分配的瓶頸也進行了有效的規(guī)避。
參考文獻
[1]姚全珠.C++面向?qū)ο蟪绦蛟O計教程[M].電子工業(yè)出版社,2010.
[2]Mastering MFC Development Abbas Jamalipoura and Pascal Lorenz Release Date:July,2003.
[3]鄭秋生.C/C++程序設計教程—— 面向?qū)ο蠓謨訹M].電子工業(yè)出版社,2008.
[4]申德榮,于戈.分布式數(shù)據(jù)庫系統(tǒng)原理與應用[M].機械工業(yè)出版社,2010.
[5]張乃孝,宗艷.數(shù)據(jù)結構—C++與面向?qū)ο蟮耐緩剑ㄐ抻啺妫M].高等教育出版社,2005.