自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Java查詢大文本文件的處理方法

開發(fā) 后端
有時(shí)我們需要查詢大文本而不是數(shù)據(jù)庫,這時(shí)就需要流式讀入文件并實(shí)現(xiàn)查詢算法,還要進(jìn)行并行處理以提高性能。但JAVA本身缺少相應(yīng)的類庫,需要硬編碼才能實(shí)現(xiàn)結(jié)構(gòu)化文件計(jì)算,代碼復(fù)雜且可讀性差,難以實(shí)現(xiàn)高效的并行處理。

有時(shí)我們需要查詢大文本而不是數(shù)據(jù)庫,這時(shí)就需要流式讀入文件并實(shí)現(xiàn)查詢算法,還要進(jìn)行并行處理以提高性能。但JAVA本身缺少相應(yīng)的類庫,需要硬編碼才能實(shí)現(xiàn)結(jié)構(gòu)化文件計(jì)算,代碼復(fù)雜且可讀性差,難以實(shí)現(xiàn)高效的并行處理。

使用免費(fèi)的集算器可以彌補(bǔ)這一不足。集算器封裝了豐富的結(jié)構(gòu)化文件讀寫和游標(biāo)計(jì)算函數(shù),書寫簡(jiǎn)單代碼就能實(shí)現(xiàn)并行計(jì)算,并提供了易用的JDBC接口。JAVA應(yīng)用程序可以將集算器腳本文件當(dāng)做數(shù)據(jù)庫存儲(chǔ)過程執(zhí)行,傳入?yún)?shù)并用JDBC獲得返回結(jié)果。

集算器與Java應(yīng)用程序的集成結(jié)構(gòu)如下: 

 

下面舉例說明集算器協(xié)助JAVA查詢大文本的基本過程。源數(shù)據(jù)sOrder.txt如下:

要查詢起止時(shí)間是startDate、endDate之間,金額大于argAmount的訂單,只需使用如下代碼: 

A1:以游標(biāo)方式打開文件。@t表示將第1行讀為列名。

A2:進(jìn)行結(jié)構(gòu)化查詢,結(jié)果為游標(biāo)。

A3:執(zhí)行游標(biāo),將結(jié)果讀入內(nèi)存,如下:

 

JAVA主程序可以JDBC的方式調(diào)用集算器腳本,代碼如下:

Class.forName("com.esproc.jdbc.InternalDriver");

con=DriverManager.getConnection("jdbc:esproc:local://");

//調(diào)用集算器腳本(類似存儲(chǔ)過程),其中searchbig是dfx的文件名

st=(com. esproc.jdbc.InternalCStatement)con.prepareCall("call searchbig");

//設(shè)置參數(shù)

st.setObject(1,"2010-01-01");

st.setObject(2,"2010-12-31");

st.setObject(3,2000);

//執(zhí)行腳本

st.execute;

//獲取結(jié)果集

ResultSetrs = st.getResultSet;

……

返回值是符合JDBC標(biāo)準(zhǔn)的ResultSet對(duì)象,調(diào)用集算器腳本和訪問數(shù)據(jù)庫的方法完全一樣,熟悉JDBC的程序員可以很快掌握。

對(duì)于上面這類較簡(jiǎn)單的代碼,還可以直接將腳本寫在JDBC調(diào)用中,多行語句之間用\n分隔即可,類似執(zhí)行一句較復(fù)雜的SQL,這樣可以不必再保存一個(gè)腳本文件。

st = (com.esproc.jdbc.InternalCStatement)con.createStatement;

ResultSet rs1 =st.executeQuery("=file(\"D:\\sOrder.txt\").import@t\n" +"=A1.select(OrderDate>=date(\"2010-01-01\") &&OrderDate<=date(\"2010-12-31\") && Amount>2000)\n"+

"=A2.fetch");

集算器會(huì)返回***一個(gè)表達(dá)式的值。

如果查詢結(jié)果內(nèi)存裝不下,可以在集算器中直接返回游標(biāo)(即去掉A3代碼),在JAVA中只需設(shè)置每批次讀取的記錄數(shù)即可正常讀取,具體代碼如下:

st.setFetchSize(1000)

關(guān)于集算器JDBC的部署和調(diào)用的更詳細(xì)信息可參考集算器集成應(yīng)用之被JAVA調(diào)用。 

集算器還可以實(shí)現(xiàn)多線程并行計(jì)算,最簡(jiǎn)單方法就是在上述代碼的cursor函數(shù)中使用@m,這表示多線程讀取文件。

也可以手工分段,在讀取和計(jì)算部分都使用多線程并行計(jì)算,代碼如下:

A1:用8個(gè)游標(biāo)打開文件,每次讀取文件的指定部分。~表示循環(huán)變量,依次是1、2…8,@z表示將文件按字節(jié)數(shù)大致分為幾部分,只讀取其中一部分,集算器會(huì)自動(dòng)去頭補(bǔ)尾,以保證取出的數(shù)據(jù)是整行。

A2:針對(duì)每個(gè)游標(biāo)執(zhí)行查詢。

A3:并行執(zhí)行游標(biāo),并合并結(jié)果。@x表示合并的對(duì)象是游標(biāo),@m表示并行計(jì)算。需要注意的是,函數(shù)conj無法保證結(jié)果順序和源數(shù)據(jù)一致。

上述代碼使用了集算器內(nèi)置的并行計(jì)算函數(shù),如果計(jì)算過程較復(fù)雜,或內(nèi)存可以裝下計(jì)算結(jié)果,則適合用顯式并行計(jì)算語句。代碼如下:

 

A1:設(shè)定并行數(shù)。

A2:并行執(zhí)行代碼,作用范圍是縮進(jìn)的B2-B3。to(A1)=[1,2…8]表示每個(gè)線程的入口參數(shù)。線程內(nèi)部可用A2來獲取入口參數(shù),線程外部可用A2獲取所有線程的計(jì)算結(jié)果。

B3:查詢游標(biāo),將結(jié)果讀入內(nèi)存,并返回給主線程。

A4:按順序合并各線程的計(jì)算結(jié)果。

對(duì)于有序數(shù)據(jù),可以用二分法來提高查詢性能。比如數(shù)據(jù)已按Client和OrderID排序,現(xiàn)在要根據(jù)參數(shù)argClient和argOrder找出相應(yīng)的記錄,可以使用下面的代碼:

begin,end是二分法的起止位置,m是中間位置。

B4:按字節(jié)數(shù)定位到中間位置,打開游標(biāo)讀入一條記錄,集算器會(huì)自動(dòng)實(shí)現(xiàn)去頭補(bǔ)尾,取出完整記錄。@x表示取出記錄后立即關(guān)閉游標(biāo)。

B5-C6:如果定位成功,則將當(dāng)前記錄存儲(chǔ)在C5。

B7-C8:如果定位不成功,則繼續(xù)比較集合大小并重新設(shè)置begin,end。

A9:將C5中的計(jì)算結(jié)果顯式地返回給JDBC。

責(zé)任編輯:王雪燕 來源: 紅黑聯(lián)盟
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)