RandomAccessFile in Java
The RandomAccessFile class in Java, in java.io, lets you read and write at any position in a file, not only from start to end like a stream. It keeps a file pointer, the current position in bytes, which you move with seek(position). This is useful for files made of fixed-size records, where record number n always starts at byte n x recordSize, so it can be read or changed without touching the rest. In this lesson, you will learn its modes and methods and update a record in place.
Constructor and Modes
public class RandomAccessFile implements DataOutput, DataInput, Closeable
new RandomAccessFile("data.bin", "rw")| Mode | Meaning |
|---|---|
"r" | It is used to open for reading only. |
"rw" | It opens for reading and writing, creating the file if needed. |
"rws" / "rwd" | Like "rw", but every write is saved to the disk immediately. |
Methods
| Method | Description |
|---|---|
seek(long pos) | It moves the file pointer to a byte position. |
getFilePointer() | It returns the current position. |
length() / setLength(n) | It returns or changes the file size. |
readInt(), readDouble(), readUTF()... | It reads values at the pointer (like DataInputStream). |
writeInt(), writeDouble(), writeUTF()... | It writes values at the pointer (like DataOutputStream). |
read(byte[]), write(byte[]) | It reads or writes raw bytes. |
Every read or write moves the pointer forward by the number of bytes used.
Example: Fixed-Size Marks Records
Let's see an example that stores each student's marks as one int (4 bytes), then changes the third record without rewriting the file.
import java.io.IOException;
import java.io.RandomAccessFile;
public class Records {
static final int SIZE = 4;
public static void main(String[] args) throws IOException {
try (RandomAccessFile file = new RandomAccessFile("marks.dat", "rw")) {
int[] marks = {91, 78, 85, 66};
for (int m : marks) {
file.writeInt(m);
}
System.out.println("Length: " + file.length() + " bytes");
file.seek(2 * SIZE);
System.out.println("Record 2: " + file.readInt());
file.seek(2 * SIZE);
file.writeInt(88);
System.out.println("Pointer after update: "
+ file.getFilePointer());
file.seek(0);
StringBuilder all = new StringBuilder();
for (int i = 0; i < file.length() / SIZE; i++) {
all.append(file.readInt()).append(' ');
}
System.out.println("All records: " + all.toString().strip());
}
}
}Length: 16 bytes
Record 2: 85
Pointer after update: 12
All records: 91 78 88 66Explanation: Four int values make a 16-byte file. Record 2 (counting from 0) starts at byte 8, so seek(8) jumps straight to it. Writing 88 there replaces 85 in place and moves the pointer to byte 12. Finally seek(0) goes back to the start to read everything.
Fixed-Size Records Only
Common Mistakes
Forgetting to seek before reading after a write. The pointer has moved past what you wrote.
Reading past the end. readInt throws EOFException.
Opening with "r" and calling a write method. It throws IOException.
Practice
- Easy: Write the numbers 1 to 10 as
intvalues, then read and print only the last three by seeking. - Harder: Store records of a 20-character name (padded) and an
intmark, and write a methodupdateMark(int index, int mark)that changes one record in place.
Key Takeaways
Was this tutorial helpful?