直接使用Java根据条件过滤文本文件中的数据会有以下问题:1.文件不是数据库,无法用SQL访问。当过滤条件改变时需要重写代码。如果要像SQL一样实现灵活的条件过滤,需要自己实现动态表达式解析求值,编程工作量非常大。2.当文件过大时,无法一次性加载到内存中处理,分步读入的方式在考虑性能时会涉及文件缓冲区管理、行拆分计算等复杂的编程.使用集算器辅助Java编程,这些问题都不需要自己写代码来解决。下面通过一个例子来看看具体的做法。员工数据保存在文本文件employee.txt中。我们要读取员工信息,查找1981年1月1日(含)以后出生的女员工。文本文件empolyee.txt的格式如下:EIDNAMESURNAMEGENDERSTATEBIRTHDAYHIREDATEDEPTSALARY1RebeccaMooreFCalifornia1974-11-202005-03-11R&D70002AshleyWilsonFNewYork1980-07-192008-03-16财务110003雷切尔·约翰逊F新墨西哥州1970-12-172010-12-01销售90004艾米丽·史密斯F得克萨斯州1985-03-072006-08-15HR7000***shleySmithF得克萨斯州1975-05-132004-07-30研发160006MatthewJohnsonM加利福尼亚1984-07-072005-07-07销售110007AlexisSmithF伊利诺伊1972-08-162002-08-16销售90008MeganWilsonFMark加利福尼亚1979-04-194198110009VictoriaDavisFTexas1983-12-072009-12-07HR300010RyanJohnsonMPennsylvania1976-03-122006-03-12R&D1300011JacobMooreMTexas1974-12-162004-12-16SalesicaJ20DavisFNewYork1980-09-112008-09-11Sales700013DanielDavisMFlorida1982-05-142010-05-14Finance10000...实现思路是:用Java程序调用集算器脚本,读取和读取计算数据,然后将结果返回给JavResultSet形式的程序。由于集算器支持动态表达式解析和求值,Java程序可以像使用SQL一样灵活地过滤文本文件中的数据。例如,我们需要查询1981年1月1日(含)以后出生的女员工,集算器程序可以从外部获取一个输入参数“where”作为条件,如下图:where是一个字符串,而值为:BIRTHDAY>=date(1981,1,1)&&GENDER=="F"。集算器代码如下:A1:定义一个文件对象,读入数据,第一行为标题,字段分隔符默认为tab。集算器集成开发环境可以直观显示导入的数据,如上图右侧所示。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”||姓名+姓氏==“丽贝卡摩尔”。执行后A2中的结果集如下图所示:在Java程序中,使用集算器JDBC调用该程序获取结果代码如下:(将上述集算器程序另存为test.dfx)://建立集算器jdbc连接Class.forName("com.esproc.jdbc.InternalDriver");con=DriverManager.getConnection("jdbc:esproc:local://");//调用集算器程序(存储过程),其中test是dfx的文件名st=(com.esproc.jdbc.InternalCStatement)con.prepareCall(“calltest(?)”);//设置参数st.setObject(1,”BIRTHDAY>=date(1981,1,1)&&GENDER==\”F\"||NAME+SURNAME==\"RebeccaMoore\"");//参数为动态过滤条件//执行集算器存储过程st.execute();//获取结果集:合格员工集合ResultSetset=st.getResultSet();对于代码比较简单的脚本,也可以直接在调用集算器JDBC的Java程序中编写代码,而不用编写脚本文件(test.dfx):st=(com.esproc.jdbc.InternalCStatement)con.createStatement();ResultSetset=st.executeQuery("=file(\"D:/employee.txt\").import@t().select(BIRTHDAY>=date(1981,1,1)&&GENDER==\”F\”||NAME+SURNAME==\”RebeccaMoore\”)”);这段Java代码直接调用集算器的一个脚本:从文本文件中获取数据,并按照指定的条件过滤后的结果集返回到ResultSet对象集。上述方法中,假设文件很小,可以完全读入内存。但实际上可能会出现文件过大无法读取内容的情况,即使可以读取也不需要占用太多内存。这种情况下,可以使用文件游标来处理。集算器程序调整如下:A1:定义一个文件对象游标,第一行为标题,字段分隔符默认为制表符。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),集算器将游标数据写入文件。
