繁体   English   中英

Java:从超大型文本文件中读取具有相同前缀的行组

[英]Java: read groups of lines with same prefix from very large text file

我有一个大型(〜100GB)文本文件,结构如下:

A,foobar
A,barfoo
A,foobar
B,barfoo
B,barfoo
C,foobar

每行是一对逗号分隔的值。 该文件按该对中的第一个值排序。 这些线是可变长度的。 将一个组定义为所有具有相同第一个值的行,即上面引用的示例中,所有以“ A”开头的行都是一个组,所有以“ B”开头的行都是另一个组。

整个文件太大,无法容纳到内存中,但是如果您从任何单个组中取出所有行,则总会容纳在内存中。

我有一个例程来处理一行这样的行并写入文本文件。 我的问题是我不知道如何一次最好地读取文件。 所有组的大小都是任意的,未知。 我考虑过两种方法:

1)使用BufferedReader扫描文件,累积来自字符串或数组中一组的行。 每当遇到属于新组的行时,将该行保留在临时变量中,即可处理前一个组。 清除累加器,添加临时项,然后从第二行开始继续读取新组。

2)使用BufferedReader扫描文件,每当遇到属于新组的一行时,都会以某种方式重置光标,以便在下次调用readLine()时,它从组的第一行而不是第二行开始。 我已经研究了mark()reset()但是这些都需要知道该行开始的字节位置。

目前,我将选择(1),但是如果有人可以提出一种气味较小的方法,我将不胜感激。

我认为PushbackReader可以工作:

 if (lineBelongsToNewGroup){
     reader.unread(lastLine.toCharArray());
     // probably also unread a newline
 }

我认为选项1是最简单的。 我会自己解析文本,而不是使用BufferedReader解析文本,因为解析100 GB需要花费一个孤独的时间。

唯一可能更快的选择是使用二进制搜索通过RandomAccessFile访问文件。 您可以在64位JVM上映射100 GB的内存。 这样就避免了解析每行的开销,而这是非常昂贵的。 这种方法的优点是可以使用多个线程。它的实现要复杂得多,但要快得多。 一旦有了每个边界,就可以批量复制原始数据,而不必解析所有行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM