观察到的行为的原因,顾名思义,缓冲读取器是缓冲的。 将大数据块n读取到缓冲区中,n只返回与缓冲区内容相关的部分,即从顶部开始的下一n行分隔符。
广义上,我认为有两种可能的方法。 你可以实现自己的缓冲逻辑。
使用一些丑陋的反射hack获取所需的缓冲区偏移
1 .不再使用random access文件#自述文件。 相反,自己选择缓冲器bytebuffer[]=newbyte[8192];//ina loop : intread=random access file.read (buffer );
//figureoutwherealinebreak `n ` appearsinthebuffer,
//returntheresultinglines,andtakethepositionofthe`n `
//intoaccountwhenstoringthe ' file pointer '
模棱两可的评论说,这可能很繁琐和繁琐。 你基本上重新实现了这个readLine方法在BufferedReader类中的作用。 在这方面,我甚至不想提及不同的行分隔符或字符集可能导致的头痛。
2 .提供了对存储缓冲区偏移量的字段的轻松访问。 这可以通过以下示例实现: 当然,这是一个有点粗糙的解决方案,但这里列出的简单备选方案取决于解决方案应该“可持续”的程度和您想做多少努力。 importjava.io.BufferedReader; importjava.io.FileReader; import Java.io.random访问文件; importjava.lang.reflect.Field; 导入
java.util.ArrayList; importjava.util.List; publicclassLargeFileRead{
publicstaticvoidmain (字符串[ ] args ) throwsException{
StringfileName='myBigFile.txt ';
longbefore=System.nanoTime (;
列表结果=读缓冲区(filename;
//list result=read default (filename );
longafter=System.nanoTime (;
双精度ms=(after-before )/1e6;
system.out.println (reading took ' ms ' ms )。
' for' result.size () ' lines );
}
私有文件缓冲区throwsException{
列表lines=new ArrayList (;
randomaccessfilerandomaccessfile=newrandomaccessfile (文件名称,' r ' );
bufferedreaderbrrafreader=newbufferedreader (
new filereader (随机访问文件. getfd ) );
字符串行=null;
longcurrentOffset=0;
longpreviousOffset=-1;
while ((line=brrafreader.readline ) )!=空) {
longfileoffset=random access file.getfile pointer (;
文件偏移!=previousOffset )
预置偏移!=-1 ()
currentOffset=previousOffset;
}
previous offset=文件offset;
}
intbufferoffset=get offset (brrafreader );
longrealposition=currentoffsetbufferoffset;
system.out.println (位置: ) real位置
' with FP ' random access file.getfile pointer (
'与偏移'缓冲器偏移;
lines.add(line;
}
返回线;
}
私有数据传输工具(bufferedreaderbufferedreader ) throws扩展{
field field=buffered reader.class.getdeclaredfield (' nextchar );
intresult=0;
try{
field.set accessible (真;
result=(integer ) field.get )缓冲读取程序;
}finally{
IELD.setaccessible(false );
}
返回结果;
}
私有文件名称throwsException{
列表lines=new ArrayList (;
randomaccessfilerandomaccessfile=newrandomaccessfile (文件名称,' r ' );
字符串行=null;
while ((line=random access file.readline ) )!=空) {
system.out.println (position : random access file.getfile pointer ) );
lines.add(line;
}
返回线;
}
(注意:偏移可能仍显示为1,这是因为位置没有考虑线条分隔符。 根据需要可调整)
注意:这只是一张草图。 读取完成后,必须正确关闭RandomAccessFile对象,这取决于超出时间限制时读取如何中断,如问题中所述