0

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

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

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

整个文件太大而无法放入内存,但是如果您从任何单独的组中取出所有行,则始终可以放入内存。

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

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

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

我现在将使用(1),但如果有人能提出一种气味较少的方法,我将不胜感激。

4

2 回答 2

2

我认为PushbackReader会起作用:

 if (lineBelongsToNewGroup){
     reader.unread(lastLine.toCharArray());
     // probably also unread a newline
 }
于 2012-08-30T08:29:50.157 回答
1

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

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

于 2012-08-30T08:30:40.593 回答