我有一个大的(~100GB)文本文件,结构如下:
A,foobar
A,barfoo
A,foobar
B,barfoo
B,barfoo
C,foobar
每一行都是以逗号分隔的值对。文件按对中的第一个值排序。线条长度可变。将一个组定义为具有共同第一个值的所有行,即上面引用的示例所有以“A”开头的行将是一个组,所有以“B”开头的行将是另一个组。
整个文件太大而无法放入内存中,但是如果你从任何一个组中取出所有的行总是适合内存。
我有一个处理单个这样的行组并写入文本文件的例程。我的问题是,我不知道如何最好一次读取一个组的文件。所有组都是任意的,未知的大小。我考虑过两种方式:
1)使用BufferedReader
扫描文件,累积字符串或数组中的组的行。每当遇到属于新组的行时,将该行保存在临时变量中,处理前一个组。清除累加器,添加临时值,然后从第二行开始继续读取新组。
2)使用BufferedReader
扫描文件,每当遇到属于新组的行时,以某种方式重置光标,以便下次调用readLine()
时从第一行开始小组而不是第二小组。我查看了mark()
和reset()
,但这些需要知道行开头的字节位置。
我现在要和(1)一起去,但如果有人能提出一种味道更少的方法,我将非常感激。
答案 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。这避免了解析相当昂贵的每一行的需要。这种方法的一个优点是你可以使用多个线程它实现起来要复杂得多,但速度要快得多。一旦有了每个边界,就可以批量复制原始数据,而无需解析所有行。