Java 有什么开源包适合处理 txt/csv?

 

CSV 文件因为具有良好的可读性,通常用于在应用程序或系统之间传输数据,作为从一个系统导出数据并将其导入另一个系统的通用格式。Java 程序员用 BufferedReader、FileWriter 和自定义错误处理,通过核心 Java IO 就能处理最基本的 CSV 读写场景。CSV 还有几个优秀的开源包,Commons CSV, OpenCSV, SuperCSV,这些包存在是因为 CSV 并不像最初看起来那么简单,在有特殊编码的情况下,不妨使用这些开源库。如果你仅仅是为了传输数据,格式简单用基本 Java IO 处理,格式复杂依靠 CSV 开源包,配置不同的参数就能解析复杂格式。

CVS 解析后通常是导入数据库,应用程序再利用数据库完成后续计算。对于需要反复利用 CVS 数据计算的场景,导入数据库是划算的,但往往导入数据库只是为了利用 SQL 来计算数据,这种情况就不妨使用既能解析 CSV 数据,又能做结构化计算的开源库。Open-esProc就是这种类型的开源包,但 Open-esProc 和一般开源包有所不同,是将数据类型和方法封装到一个叫 SPL 的脚本语言中,然后在 Java 程序中调用 SPL 脚本,返回 ResultSet 对象。

比如:找出英语平均分低于70分的班级。SPL 代码如下:


A

1

=file(“E:/txt/Students_scores.csv”).import@tc()

2

=A1.groups(CLASS;avg(English):avg_En)

3

=A2.select(avg_En<70)

完成上述任务,直接用 Java 显然代码十分冗长,但用 SPL 从解析文本(只需要在 @后提供合适参数选项,就可以对文本进行快速解析),到结构化计算(对数据集过滤、排序、分组统计、连接等)都非常简单。脚本文件(比如 condition.dfx)和 Java 存储在一起,通过 JDBC 接口在 JAVA 中调用,用法类似存储过程。这样,CSV 计算过程都是独立的,当遇到需求变动后,改动也非常方便。

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

SPL 也支持类似 SQL 的用法,无须脚本文件,直接将其嵌入 JAVA

…
 ResultSet result = statement.executeQuery("
=file(\“E:/txt/Students_scores.csv\”).import@tc()
.groups(CLASS;avg(English):avg_En).select(avg_En<70)");
…

SPL 中还提供了用 SQL 查询文件数据的方法,方便熟悉 SQL 的程序直接使用。比如:州信息,部门信息和员工信息分别存储在三个文本文件中,查询经理在 California 州的 New York 州员工。


A

1

$select   e.NAME as ENAME
from   E:/txt/EMPLOYEE.txt  as e
     join E:/txt/DEPARTMENT.txt as d on   e.DEPT=d.NAME
     join E:/txt/EMPLOYEE.txt  as emp on d.MANAGER=emp.EID
where   e.STATE='New York' and emp.STATE='California'

用开源包解析 CSV 文件比较头疼的是遇到大文件,因为开源包都是将数据一次性读入或逐行读入内存的,当数据很大时,内存大小就会形成处理的瓶颈。SPL 通过游标读取的方式,类似数据库中的游标,做小批量读取,然后在游标上绑定计算,实现排序、关联和分组计算,这样就可以利用小内存完成大数据的计算。


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 应用计算之文件计算