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

时间:2012-08-30 08:24:05

标签: java file text line bufferedreader

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

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

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

整个文件太大而无法放入内存中,但是如果你从任何一个组中取出所有的行总是适合内存。

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

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

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

我现在要和(1)一起去,但如果有人能提出一种味道更少的方法,我将非常感激。

2 个答案:

答案 0 :(得分:2)

我认为PushbackReader可行:

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

答案 1 :(得分:1)

我认为选项1是最简单的。我会自己解析文本,而不是使用BufferedReader,因为它只需要一次解析100 GB。

可能更快的唯一选择是使用使用RandomAccessFile访问文件的二进制搜索。您可以在64位JVM上将内存映射为100 GB。这避免了解析相当昂贵的每一行的需要。这种方法的一个优点是你可以使用多个线程它实现起来要复杂得多,但速度要快得多。一旦有了每个边界,就可以批量复制原始数据,而无需解析所有行。