我有一个非常大的(11GB).json文件(是的,谁会认为这是个好主意?),我需要对其进行抽样(读取 k
行随机行)。
我不太熟悉Java文件IO,但我当然找到了这篇帖子:如何在Java中获取文本文件的随机行?
我放弃了被接受的答案,因为显然读取一个11GB的文件的每一行来选择其中一行(或者说 k
行)太慢了,而且行数约为10万行。
幸运的是,在那里还有第二个建议,我认为它可能更适合我:
使用RandomAccessFile在文件中寻找一个随机字节位置。
向左和向右查找下一个行终止符。让L为它们之间的行。
以(MIN_LINE_LENGTH / L.length)的概率返回L。否则,回到步骤1。
到目前为止都很好,但我想知道“让L为它们之间的行”是什么意思。
我会做这样的事情(未经测试):
RandomAccessFile raf = ...
long pos = ...
String line = getLine(raf,pos);
...
在哪里
private String getLine(RandomAccessFile raf, long start) throws IOException{
long pos = (start % 2 == 0) ? start : start -1;
if(pos == 0) return raf.readLine();
do{
pos -= 2;
raf.seek(pos);
}while(pos > 0 && raf.readChar() != '\n');
pos = (pos <= 0) ? 0 : pos + 2;
raf.seek(pos);
return raf.readLine();
}
然后使用line.length()
操作,无需显式地寻找行的右端。
那么为什么需要“向左和向右查找下一个行结束符”? 有没有更方便的方法从这两个偏移量获得行?