Java 有什么开源包能处理巨大文本?

 

随着 JDK 版本的升级,JAVA 对大文本流式读取提供了更好的解决方法,配合调整 Jvm 堆的大小,能处理文本的大小和读取效率都大大提升了。如果文本比较规范,利用开源包 Commons CSV, OpenCSV, SuperCSV 等都能进一步简化处理。快速读取或解析大文本不是最终目的,绝大多数数据读取的最终目的地都去了数据库、大数据处理引擎、云计算存储,在那里等着被再次计算。但现实中很多需求,实际不需要反复计算,比如对比两个大文本找出差异数据,在 1T 的文本数据做一次条件筛选出想要的数据等。这类需求导入数据库都很费时费力,当没有软硬件条件时,Java 程序员就需要耗费很大的精力去实现相关计算。

如果有个更高级的类库,不仅能流式高效的读取数据,又能协同应用程序在本机完成 SQL 那样计算动作,将会非常便利。在开源领域,功能丰富且简单易用的这类计算包Open-esProc比较领先,但 Open-esProc 和一般开源包有所不同,是将数据类型和方法封装到一个叫 SPL 的脚本语言中,然后在 Java 程序中调用 SPL 脚本,返回 ResultSet 对象。

先介绍一个用 Open-esProc 比较简单的例子。比如,从文件 emplyee.csv 中查询出 1981 年 1 月 1 日(含)之后出生的女员工,SPL 脚本如下:


A

1

=file("D:/emplyee.csv").cursor@tc()

2

=A1.select(BIRTHDAY>=date("1981-01-01") && GENDER=="M")

3

=A1.fetch()

SPL 通过游标读取的方式,类似数据库中的游标,做小批量流式读取,然后在游标上绑定计算,实现过滤、分组和关联等计算,这样就可以利用小内存完成大数据的计算。

如果条件是不定的,可以将 A2 的代码改为:A1.select(${where}),这样就可以将查询条件写在 where 参数里,实现动态查询。如果查询结果较多,内存放不下,还可以将 A3 改为 file(“D:/result.txt”).export(A2),这可以将计算结果直接输出到文件中。

除了上面这种写法外,SPL 还支持用嵌入 SQL 查询 csv 文件,如 =connect().query(“select * from D:/emplyee.csv where”+where)

脚本文件(比如 condition.dfx)和 Java 存储在一起,通过 JDBC 接口在 JAVA 中调用,用法类似存储过程。

…
 ResultSet result = statement.executeQuery("call condition.dfx");
…

再比如,对比两个大文件找不同:现有全国房产产权人员总表all.txtWashington房产产权人员登记表,请检查总表中是否有遗漏的Washington人员,结果记录在lost_w.txt中。

SPL脚本如下:


A

注释

1

=file("e:/txt/washington.txt").cursor@s().sortx(_1)

创建Washington数据游标,并排序

2

=file("e:/txt/all.txt").cursor@s().sortx(_1)

创建全国的数据游标,并排序

3

=[A1,A2].mergex@d()

对两游标数据进行有序归并,@d表示从A1中去掉A2中的所有人员,即总表中遗漏的Washington人员

4

=file("e:/txt/lost_w.txt").export(A3)

将算出的结果写入文件lost_w.txt

导入数据库经常是为了做关联计算,如果在 Java 计算包中就能完成关联计算,将非常便利。


A

1

=file("E:/txt/Employees.txt").cursor@t().sortx(EId)

2

=file("E:/txt/Orders.txt").cursor@t().sortx(SellerId)

3

=joinx(A2:O,SellerId; A1:E,EId)

4

=A3.groups(E.Dept;sum(O.Amount))

大文本处理经常需要加入并行计算提高计算效率,每个线程各自用大文件计算的方式处理一段数据,最后将各线程处理的结果进行汇总。

A
1 =file(“E:/txt/user_info_reg.csv”).cursor@tcm(;4)
2 =A1.groups(id_province;count(~):cnt)

在 SPL 中使用并行提速非常容易,@m 表示并行计算,参数 4 表示 4 路并行,与单线程代码相比,仅仅多一个游标选项与参数,让用户使用并行非常方便。

更多计算示例,可以参考SPL 应用计算之文件计算