Java 使用 RandomAccessFile 到达文件中的特定行

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9769874/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 07:27:21  来源:igfitidea点击:

Reaching a specific line in a file using RandomAccessFile

javafilerandom-access

提问by Vicky

Is it possible to position cursor to the start of a specific line in a file through RandomAccessFile?

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

For e.g. I want to change String starting at char 10 till 20 in line 111 in a file. The file has fixed length records.

例如,我想将字符串从文件中的第 111 行的字符 10 开始更改为 20。该文件具有固定长度的记录。

Is it possible to directly position the cursor to start of line 111 using RandomAccessFile ?

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

Update:

更新:

I used the following code. However, its returning null.

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

Line length is 200 characters (which is 200 bytes if I am not wrong)

行长是 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());

Where am I going wrong ?

我哪里错了?

采纳答案by mishadoff

I'm not sure but seems RandomAccessFile do not support such functionality. As RAF operates with bytes we can skip specific amount of bytes, and if your file has fixed line width this can be achieved by

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

file.skipBytes(110 * lineSizeInBytes);

Otherwise, you need something like this:

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

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

回答by AlexR

You cannot do this directly with RandomAccessFile. It is attended to work with binary files and helps you to read and write such files fragment at any randomlocation you want. This is why the class is called RandomAccessFile.

您不能直接使用RandomAccessFile. 它负责处理二进制文件,并帮助您在您想要的任何随机位置读取和写入此类文件片段。这就是该类被称为RandomAccessFile.

But it does no work with texts, so it does not have a way to recognize end of line and does not work in terms of lines at all.

但是它不适用于文本,因此它无法识别行尾,并且根本无法在行方面工作。

So, to implement what you want you should use BufferedReader, read line-by-line and if you want store position where each line is started, so you will be able to skip required number of bytes to jump to the beginning of needed line.

所以,要实现你想要的,你应该使用BufferedReader,逐行读取,如果你想存储每行开始的位置,那么你将能够跳过所需的字节数以跳转到所需行的开头。

回答by Hot Licks

To use RandomAccessFile you either need to have fixed-length records or have a "dope vector" of offsets to the start of each record (or, eg, every 10th record). These may or may not be appropriate to your problem.

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

回答by wattostudios

As some other people have stated, there are other classes that are specifically designed to read lines of text, such as BufferedReader. However, if you are required to use RandomAccessFile, you can read lines of text, but you need to programmatically find where 1 line ends and another line begins...

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

A simple example may be...

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

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;
    }
  }

This gives the basic building block for a reader that looks for the end of each line.

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

If you intend to go down the path of using RandomAccessFile, you can start with this framework, but you need to be aware of a number of drawbacks and got-ya's such as... 1. Unix and Windows use different line markers - you'll need to look for '\n', '\r' and a combination of both of these 2. Reading a single byte at a time is very slow - you should read a block of bytes into an array buffer (eg a byte[2048] array) and then iterate through the array, refilling the array from the RandomAccessFile when you reach the end of the buffer array. 3. If you are dealing with Unicode characters, you need to read and process 2 bytes at a time, rather than single bytes.

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

RandomAccessFile is very powerful, but if you can use something like BufferedReader then you'd probably be much better to use that instead, as it takes care of all these issues automatically.

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