有时候我们需要查询大文本而不是数据库。这时候我们就需要对文件进行流式处理和实现查询算法,同时还要进行并行处理来提高性能。但是JAVA本身缺少相应的类库,需要硬编码才能实现结构化文件计算。代码复杂,可读性差,难以实现高效的并行处理。使用免费的集算器可以弥补这一不足。集算器封装了丰富的结构化文件读写和游标计算函数,只需编写简单的代码即可实现并行计算,并提供简单易用的JDBC接口。JAVA应用程序可以将集算器脚本文件作为数据库存储过程执行,传入参数并使用JDBC获取返回结果。集算器与Java应用的集成结构如下:下面举例说明集算器辅助JAVA查询大文本的基本过程。源数据sOrder.txt如下:查询起止时间在startDate和endDate之间,且金额大于argAmount的订单,只需使用如下代码:A1:用光标打开文件。@t表示将第1行读取为列名。A2:执行结构化查询,结果是一个游标。A3:执行游标,将结果读入内存,如下:JAVA主程序可以通过JDBC方式调用集算器脚本,代码如下:Class.forName("com.esproc.jdbc.InternalDriver");con=DriverManager.getConnection("jdbc:esproc:local://");//调用集算器脚本(类似存储过程),其中searchbig为dfx的文件名st=(com.esproc.jdbc.InternalCStatement)con.prepareCall("callsearchbig");//设置参数st.setObject(1,"2010-01-01");st.setObject(2,"2010-12-31");st.setObject(3,2000);//执行脚本st.execute;//获取结果集ResultSetrs=st.getResultSet;...返回值为符合JDBC标准的Res??ultSet对象。调用集算器脚本和访问数据库的方法完全一样,熟悉JDBC的程序员可以很快掌握。对于上述比较简单的代码,也可以直接在JDBC调用中编写脚本,多行语句用\n分隔,类似于执行比较复杂的SQL语句,这样就不需要保存一个脚本文件。st=(com.esproc.jdbc.InternalCStatement)con.createStatement;ResultSetrs1=st.executeQuery("=file(\"D:\\sOrder.txt\").import@t\n"+"=A1.选择(OrderDate>=date(\"2010-01-01\")&&OrderDate<=date(\"2010-12-31\")&&Amount>2000)\n"+"=A2.fetch");set计算器返回最后一个表达式的值。如果查询结果放不下内存,可以直接在集算器中返回游标(即去掉A3代码)。在JAVA中,只需要设置每批读取的记录数即可正常读取。具体代码如下:st.setFetchSize(1000)关于集算器JDBC的部署和调用,请参考JAVA调用集算器集成应用。集算器还可以实现多线程并行计算。最简单的方法就是在上面代码的游标函数中使用@m,即多线程读取文件。也可以手动切分,在读取和计算部分都采用多线程并行计算。代码如下:A1:用8个游标打开文件,每次读取文件的指定部分。~表示循环变量,依次为1、2...8,@z表示根据字节数将文件大致分成几部分,只读取一部分。全线。A2:对每个游标执行查询。A3:并行执行游标并合并结果。@x表示合并后的对象是游标,@m表示并行计算。需要注意的是,函数conj不能保证结果序列与源数据一致。上述代码使用了集算器内置的并行计算功能。如果计算过程比较复杂,或者计算结果可以存储在内存中,适合使用显式并行计算语句。代码如下:A1:设置并机号。A2:并行执行代码,作用范围为缩进的B2-B3。to(A1)=[1,2...8]表示每个线程的入口参数。可以在线程内部使用A2获取入口参数,在线程外使用A2获取所有线程的计算结果。B3:查询游标,将结果读入内存,返回主线程。A4:按顺序合并每个线程的计算结果。对于有序数据,可以使用二分法来提高查询性能。例如,数据已按Client和OrderID排序。现在根据参数argClient和argOrder找到对应的记录,可以使用如下代码:begin、end为二分法的开始和结束位置,m为中间位置。B4:根据字节数定位到中间位置,打开游标读取一条记录,集算器自动去头补尾,取出完整记录。@x表示在获取记录后立即关闭游标。B5-C6:如果定位成功,则当前记录存入C5。B7-C8:如果定位不成功,继续比较集合的大小,重新设置begin、end。A9:将C5中的计算结果显式返回给JDBC。
