跳到一条线并阅读它

我必须处理大文件(许多GB)并需要快速查找以根据请求检索特定行。

我们的想法是保持映射:

some_key -> byte_location 

其中字节位置表示行开始的文件中的位置。

编辑:问题有所改变:

首先我用过:

 FileInputStream stream = new FileInputStream(file); BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); FileChannel channel = stream.getChannel(); 

我注意到FileChannel.position()不会返回读者当前正在阅读的确切位置,因为它是一个“缓冲”阅读器。 它读取给定大小的块(这里是16k),所以我从FileChannel获得的是16k的倍数,而不是读者实际读取的确切位置。

PS:文件是UTF-8

我会尝试这样的事情:

  RandomAccessFile raf = new RandomAccessFile(file); ... raf.seek(position); raf.readLine(); ... 

问题是readLine()将每个字节转换为前8位为零的字符。 如果您的文件是ASCII或Latin-1,那就没问题,但UTF-8有问题。

但是,如果您准备使用RandomAccessFile来编写文件,则可以使用readUTF()writeUTF()来读取和写入编码为修改后的UTF-8字符串的“行”。

跟进

该死的… utf-8字符被搞砸了

是的…见上文。

使用RandomAccessFile处理UTF-8的另一个想法:

  1. 寻求理想的位置,
  2. 使用readFully(byte[])方法将一串字节读入byte[]
  3. 找到pos ==缓冲区中行尾的位置,
  4. 如果没有找到,请读取更多字节,连接并转到步骤2。
  5. 如果找到,则使用new String(bytes, 0, pos, UTF-8)转换为Java String。

这比使用readLine()更麻烦,但是当以随机顺序从文件中读取多行时,它应该比使用FileInputStreamskip()更快。

有什么理由不创建FileInputStream ,调用stream.skip(pos)然后围绕它创建一个InputStreamReader ,并在InputStreamReader周围创建一个BufferedReader