集算器協助Java處理結構化文本之條件過濾

來源:互聯網
上載者:User

集算器協助Java處理結構化文本之條件過濾

直接用Java實現文字檔中資料按條件過濾會有如下的麻煩:

1、檔案不是資料庫,不能用SQL訪問。當過濾條件變化時需要改寫代碼。如果要實現象SQL那樣靈活的條件過濾,則需要自己實現動態運算式解析和求值,編程工作量非常大。

2、檔案太大時不能一次性裝入記憶體處理,而採用逐步讀入方式在考慮到效能時又會涉及到檔案緩衝區管理、拆行計算等複雜編程。

使用集算器來輔助Java編程,這些問題都不需要自己寫代碼解決。下面我們通過例子來看一下具體作法。

文字檔employee.txt中儲存了員工資料。我們要讀取員工資訊,從中找出1981年1月1日含)之後出生的女員工。

文字檔empolyee.txt的格式如下:

EID NAME SURNAME GENDER STATE BIRTHDAY HIREDATE DEPT SALARY
    1 Rebecca Moore F California 1974-11-20 2005-03-11 R&D 7000
    2 Ashley Wilson F New York 1980-07-19 2008-03-16 Finance 11000
    3 Rachel Johnson F New Mexico 1970-12-17 2010-12-01 Sales 9000
    4 Emily Smith F Texas 1985-03-07 2006-08-15 HR 7000
    5 Ashley Smith F Texas 1975-05-13 2004-07-30 R&D 16000
    6 Matthew Johnson M California 1984-07-07 2005-07-07 Sales 11000
    7 Alexis Smith F Illinois 1972-08-16 2002-08-16 Sales 9000
    8 Megan Wilson F California 1979-04-19 1984-04-19 Marketing 11000
    9 Victoria Davis F Texas 1983-12-07 2009-12-07 HR 3000
    10 Ryan Johnson M Pennsylvania 1976-03-12 2006-03-12 R&D 13000
    11 Jacob Moore M Texas 1974-12-16 2004-12-16 Sales 12000
    12 Jessica Davis F New York 1980-09-11 2008-09-11 Sales 7000
    13 Daniel Davis M Florida 1982-05-14 2010-05-14 Finance 10000
    …

實現的思路是:用Java程式調用集算器指令碼,讀取和計算資料,之後將結果以ResultSet的方式返回給Java程式。由於集算器支援動態運算式解析和求值,使得Java程式可以像使用sql那樣,靈活的過濾文字檔中的資料。

例如,我們需要查詢1981年1月1日含)之後出生的女員工,esProc程式可以從外部獲得一個輸入參數“where”作為條件,如:

where是個字串,取值是:BIRTHDAY>=date(1981,1,1) && GENDER==”F”。

esProc代碼如下:

A1:定義一個file對象,讀入資料,第一行是標題,欄位分隔符號預設是tab。esProc的整合式開發環境可以直觀的顯示出匯入的資料,如右邊部分。

A2:按照條件過濾。這裡使用宏來實現動態解析運算式,其中的where就是傳入參數。集算器先計算${…}裡的運算式,將計算結果作為宏字串值 替換${…}之後解釋執行。這個例子中最終執行的是:=A1.select(BIRTHDAY>=date(1981,1,1) && GENDER==”F”)。

A3:向外部程式返回合格結果集。

過濾條件發生變化時不用改變代碼,只需改變where參數即可。例如,條件變為:查詢1981年1月1日含)之後出生的女員工,或者 NAME+SURNAME等於”RebeccaMoore”的員工。Where的參數值可以寫 為:BIRTHDAY>=date(1981,1,1) && GENDER==”F” || NAME+SURNAME==”RebeccaMoore”。執行之後,A2中的結果集如:

在Java程式中使用esProc JDBC調用這段程式獲得結果的代碼如下:將上述esProc程式儲存為test.dfx):

//建立esProc jdbc串連
    Class.forName(“com.esproc.jdbc.InternalDriver”);
    con= DriverManager.getConnection(“jdbc:esproc:local://”);
    //調用esProc 程式預存程序),其中test是dfx的檔案名稱
    st =(com.esproc.jdbc.InternalCStatement)con.prepareCall(“call test(?)”);
    //設定參數
    st.setObject(1,” BIRTHDAY>=date(1981,1,1) && GENDER==\”F\” ||NAME+SURNAME==\”RebeccaMoore\”");//參數就是動態過濾條件
    //執行esProc預存程序
    st.execute();
    //擷取結果集:合格員工集合
    ResultSet set = st.getResultSet();

對於代碼較簡單的指令碼,還可以把代碼直接寫在調用集算器JDBC的Java程式中,而不必專門編寫指令檔test.dfx):
    st=(com. esproc.jdbc.InternalCStatement)con.createStatement();
    ResultSet set= st.executeQuery(“=file(\”D:/employee.txt\”).import@t().select(BIRTHDAY>=date(1981,1,1)&&GENDER==\”F\” || NAME+SURNAME==\”RebeccaMoore\”)”);

這段Java代碼直接調用了集算器的一句指令碼:從文字檔中取得資料,並按照指定的條件過濾。結果集返回給ResultSet對象set。

上面方法中假定檔案較小,可以全部讀入記憶體。但實際上可能發生檔案較大無法讀入內容的情況,而且即使可以讀入也沒必要佔太多記憶體,這時可以使用檔案遊標的方式來處理。集算器程式調整如下:

A1:定義一個file對象遊標,第一行是標題,欄位分隔符號預設是tab。

A2:按照條件過濾遊標。這裡使用宏來實現動態解析運算式,其中的where就是傳入參數。集算器將先計算${…}裡的運算式,將計算結果作為宏字 符串值替換${…}之後解釋執行。這個例子中最終執行的是:=A1.select(BIRTHDAY>=date(1981,1,1) && GENDER==”F”)。

A3:返回遊標。

雖然集算器給Java返回的是遊標,但是Java調用的程式不用修改。在Java使用ResultSet遍曆資料的時候集算器會自動取出遊標對應的內容。

如果需要將過濾後的資料寫入另一個檔案而不是返回給主程式,只要將A3格的運算式改成:=file(“D:/employee_group.txt”).export@t(A2)即可,集算器將把遊標資料寫出成檔案。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.