【问题标题】:Reaching a specific line in a file using RandomAccessFile使用 RandomAccessFile 到达文件中的特定行
【发布时间】:2012-03-19 12:07:41
【问题描述】:

是否可以通过 RandomAccessFile 将光标定位到文件中特定行的开头?

例如我想在文件的第 111 行更改从字符 10 到 20 的字符串。该文件有固定长度的记录。

是否可以使用 RandomAccessFile 将光标直接定位到第 111 行的开头?

更新:

我使用了以下代码。但是,它返回 null。

行长为 200 个字符(如果我没记错的话是 200 个字节)

File f = new File(myFile); 
RandomAccessFile r = new RandomAccessFile(f,"rw"); 
r.skipBytes(200 * 99);   // linesize * (lineNum - 1) 
System.out.println(r.readLine());

我哪里错了?

【问题讨论】:

    标签: java file random-access


    【解决方案1】:

    我不确定,但似乎 RandomAccessFile 不支持此类功能。 由于 RAF 使用字节操作,我们可以跳过特定数量的字节,如果您的文件具有固定的行宽,则可以通过

    file.skipBytes(110 * lineSizeInBytes);
    

    否则,你需要这样的东西:

    for (int i = 0; i < 110; i++) file.readLine();
    String line = file.readLine();
    

    【讨论】:

    • 每一行包含 \n 字符。所以,实际上你应该跳过 lineCount * (lineSize + 1)。
    【解决方案2】:

    您不能直接使用RandomAccessFile 执行此操作。它负责处理二进制文件,并帮助您在所需的任何随机位置读取和写入此类文件片段。这就是为什么这个类被称为RandomAccessFile

    但是它对文本不起作用,所以它没有办法识别行尾,而且根本就行不工作。

    所以,要实现你想要的,你应该使用BufferedReader,逐行读取,如果你想存储每行开始的位置,这样你就可以跳过所需的字节数来跳转到所需行的开头。

    【讨论】:

    • +1,但 OP 迟来评论说该文件有固定长度的记录。
    • @Andrew Thompson,你是对的。我没有注意这个细节。
    • 不,它只是在您的答案发布后 被提及。我将其编辑到问题中,以避免进一步混淆。
    【解决方案3】:

    要使用 RandomAccessFile,您要么需要有固定长度的记录,要么需要在每条记录的开头(或者,例如,每 10 条记录)有一个“涂料向量”偏移量。这些可能适合也可能不适合您的问题。

    【讨论】:

      【解决方案4】:

      正如其他人所说,还有其他专门设计用于读取文本行的类,例如 BufferedReader。但是,如果您需要使用 RandomAccessFile,您可以读取文本行,但您需要以编程方式查找 1 行结束和另一行开始的位置...

      一个简单的例子可能是......

      RandomAccessFile raf = new RandomAccessFile("c:\test.txt","r");
      String line = "";
      while (raf.available()){
        byte b = raf.read();
        if (b == '\n'){
          // this is the end of the current line, so prepare to read the next line
          System.out.println("Read line: " + line);
          line = "";
          }
        else {
          line += (char)b;
          }
        }
      

      这为查找每行末尾的阅读器提供了基本构建块。

      如果你打算走上使用 RandomAccessFile 的道路,你可以从这个框架开始,但你需要知道一些缺点和得到的,比如...... 1. Unix 和 Windows 使用不同的行标记 - 您需要查找 '\n'、'\r' 以及这两者的组合 2. 一次读取一个字节非常慢 - 您应该将一个字节块读入数组缓冲区(例如 byte[2048] 数组),然后遍历数组,当您到达时从 RandomAccessFile 重新填充数组缓冲区数组的末尾。 3.如果是处理Unicode字符,需要一次读取和处理2个字节,而不是单个字节。

      RandomAccessFile 非常强大,但如果您可以使用 BufferedReader 之类的东西,那么使用它可能会更好,因为它会自动处理所有这些问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-10-09
        • 1970-01-01
        • 1970-01-01
        • 2019-06-25
        • 1970-01-01
        • 1970-01-01
        • 2013-05-02
        • 1970-01-01
        相关资源
        最近更新 更多