Java查询大文本文件的处理方法

有时我们需要查询大文本而不是数据库,这时就需要流式读入文件并实现查询算法,还要进行并行处理以提高性能。但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("call
searchbig()");

//设置参数

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

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

st.setObject(3,2000);

//执行脚本

st.execute();

//获取结果集

ResultSetrs = st.getResultSet();

……

返回值是符合JDBC标准的ResultSet对象,调用集算器脚本和访问数据库的方法完全一样,熟悉JDBC的程序员可以很快掌握。

对于上面这类较简单的代码,还可以直接将脚本写在JDBC调用中,多行语句之间用\n分隔即可,类似执行一句较复杂的SQL,这样可以不必再保存一个脚本文件。

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

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

"=A2.fetch()");

集算器会返回最后一个表达式的值。

如果查询结果内存装不下,可以在集算器中直接返回游标(即去掉A3代码),在JAVA中只需设置每批次读取的记录数即可正常读取,具体代码如下:

st.setFetchSize(1000)

关于集算器JDBC的部署和调用的更详细信息可参考集算器集成应用之被JAVA调用

集算器还可以实现多线程并行计算,最简单方法就是在上述代码的cursor函数中使用@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。

时间: 2024-12-26 16:07:58

Java查询大文本文件的处理方法的相关文章

Java查询大文本

但JAVA本身缺少相应的类库,需要硬编码才能实现结构化文件计算,代码复杂且可读性差,难以实现高效的并行处理. 使用免费的集算器可以弥补这一不足.集算器封装了丰富的结构化文件读写和游标计算函数,书写简单代码就能实现并行计算,并提供了易用的JDBC接口.JAVA应用程序可以将集算器脚本文件当做数据库存储过程执行,传入参数并用JDBC获得返回结果 下面举例说明集算器协助JAVA查询大文本的过程. 源数据sOrder.txt如下: 要查询起止时间是startDate.endDate之间,金额大于argA

Java读写大文本文件(2GB以上)

如下的程序,将一个行数为fileLines的文本文件平均分为splitNum个小文本文件,其中换行符'r'是linux上的,windows的java换行符是'\r\n': package kddcup2012.task2.FileSystem; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import 

java读取大文本文件

原文:http://blog.csdn.net/k21325/article/details/53886160 小文件当然可以直接读取所有,然后放到内存中,但是当文件很大的时候,这个方法就行不通了,内存不是这么玩的~~ 那么,下面是解决方法: 1.Java底层:调用java的java.util.Scanner类扫描文件内容,一行一行,连续读取 FileInputStream inputStream = null; Scanner sc = null; try { inputStream = ne

R实现大文本文件数据分组汇总的方法

使用R语言对文件数据分组汇总是很普遍的操作,但有时我们会遇到比较大的文件,这类文件的计算结果较小,但源数据太大,无法全部放入内存进行计算,只能采用分批读取.分批计算.拼合结果的办法来解决.下面用一个例子来说明R实现大文件数据分组汇总的方法. 有个1G的文件sales.txt,存储着大量订单记录,我们要对CLIENT字段分组并对AMOUNT字段汇总.该文件的列分割符为"\t",前几行数据如下: R语言解决方案     con <- file("E: \\sales.txt

基于Java的Jess功能函数扩展方法

Jess是Java expert system shell的缩写,是Java平台上的规则引擎,它是CLIPS程序设计语言的超集,是完全使用Java语言编写一种用于开发专家系统的语言.对于基于规则的推理,特别是针对逻辑条件的推理,Jess是已知规则引擎中最快的.它以增强型Rete算法为基础,支持前向推理,也支持后向推理,具有直接对Java对象进行推理,支持对工作存储区的查询访问等特点[1-2]. Jess语言本身提供了很多功能强大的函数供专家系统开发者调用,但这些函数不可能囊括一切功能和运算,若仅

java filechannel大文件的读写

java读取大文件 超大文件的几种方法 转自:http://wgslucky.blog.163.com/blog/static/97562532201332324639689/ java 读取一个巨大的文本文件既能保证内存不溢出又能保证性能 2010-09-25 11:18:50|  分类: 默认分类 |字号 订阅 import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.

【原创】用JAVA实现大文件上传及显示进度信息

用JAVA实现大文件上传及显示进度信息 ---解析HTTP MultiPart协议 一. 大文件上传基础描述: 各种WEB框架中,对于浏览器上传文件的请求,都有自己的处理对象负责对Http MultiPart协议内容进行解析,并供开发人员调用请求的表单内容. 比如: Spring 框架中使用类似CommonsMultipartFile对象处理表二进制文件信息. 而.NET 中使用HtmlInputFile/ HttpPostedFile对象处理二进制文件信息. 优点:使用框架内置对象可以很方便的

详解Java解析XML的四种方法

(1)DOM解析 DOM是html和xml的应用程序接口(API),以层次结构(类似于树型)来组织节点和信息片段,映射XML文档的结构,允许获取 和操作文档的任意部分,是W3C的官方标准 [优点] ①允许应用程序对数据和结构做出更改. ②访问是双向的,可以在任何时候在树中上下导航,获取和操作任意部分的数据. [缺点] ①通常需要加载整个XML文档来构造层次结构,消耗资源大. [解析详解] ①构建Document对象: DocumentBuilderFactory dbf = DocumentBu

Java中的equals和hashCode方法

本文转载自:Java中的equals和hashCode方法详解 Java中的equals方法和hashCode方法是Object中的,所以每个对象都是有这两个方法的,有时候我们需要实现特定需求,可能要重写这两个方法. equals()和hashCode()方法是用来在同一类中做比较用的,尤其是在容器里如set存放同一类对象时用来判断放入的对象是否重复.这里我们首先要明白一个问题: equals()相等的两个对象,hashcode()一定相等,equals()不相等的两个对象,却并不能证明他们的h