Reaching a specific line in a file using RandomAccessFile
Asked Answered
H

4

7

Is it possible to position cursor to the start of a specific line in a file through 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.

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

Update:

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

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

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 ?

Halo answered 19/3, 2012 at 12:7 Comment(0)
L
4

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

file.skipBytes(110 * lineSizeInBytes);

Otherwise, you need something like this:

for (int i = 0; i < 110; i++) file.readLine();
String line = file.readLine();
Laic answered 19/3, 2012 at 12:21 Comment(1)
Each line contains \n character. So, in fact you should skip lineCount * (lineSize + 1).Laic
C
4

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 random location you want. This is why the class is called 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.

Condemn answered 19/3, 2012 at 12:18 Comment(3)
+1, but the OP belatedly commented that the file has fixed length records.Stockton
@Andrew Thompson, you are right. I did not pay attention on this detail.Condemn
No, it was only mentioned after your answer was posted. I edited it into the question, to help avoid further confusion.Stockton
L
4

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

file.skipBytes(110 * lineSizeInBytes);

Otherwise, you need something like this:

for (int i = 0; i < 110; i++) file.readLine();
String line = file.readLine();
Laic answered 19/3, 2012 at 12:21 Comment(1)
Each line contains \n character. So, in fact you should skip lineCount * (lineSize + 1).Laic
B
2

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.

Bandbox answered 19/3, 2012 at 12:23 Comment(0)
Z
1

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...

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 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.

Zackzackariah answered 19/3, 2012 at 12:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.