我有大文件(每个4.5 GB),需要计算每个文件中以给定标记开头的行数。每个文件最多可以出现200k个令牌。
实现如此庞大的文件遍历和字符串检测的最快方法是什么?使用Scanner
和String.startsWith()
?
public static int countOccurences(File inputFile, String token) throws FileNotFoundException {
int counter = 0;
try (Scanner scanner = new Scanner(inputFile)) {
while (scanner.hasNextLine()) {
if (scanner.nextLine().startsWith(token)) {
counter++;
}
}
}
return counter;
}
注意:
Scanner
是瓶颈(即如果我添加比令牌检测更复杂的处理并将其应用于所有行,则整体执行时间或多或少相同。)提前感谢您的帮助。
答案 0 :(得分:1)
一些指针(假设线条相对较短且数据实际上是ASCII或类似的):
一次读取一个巨大的字节缓冲区(比如1/4 GB),然后切断不完整的行以预先添加到下一个读取。
搜索字节,不要浪费时间转换为字符
通过'\ n'开始搜索模式表示“行首,专门处理第一行
使用高速搜索,以牺牲预处理为代价缩短搜索时间(google用于“快速子字符串搜索”)
如果需要实际的行号(而不是行),请在单独的阶段计算行数
答案 1 :(得分:1)
我们可以减少在字节流中搜索\n<token>
的问题。在这种情况下,一种快速的方法是从磁盘顺序读取一大块数据(大小是根据经验确定的,但一个好的起点是1024页),并将该数据交给另一个线程进行处理。