Skip to Content
Course content

268: RandomAccessFile for Direct File Access

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Imagine you're using an old-school vinyl record player. If you want to hear the third song on the album, you don't have to sit through the first two songs and wait for the record to play naturally to that point. Instead, you just lift the needle and drop it exactly where the third track begins. You've "jumped" directly to the data you wanted without processing everything that came before it.

That's exactly how RandomAccessFile works in Java. Up until now, you've likely used streams or readers that are sequential—you start at byte 0 and read until the end. But RandomAccessFile treats a file like a giant array of bytes. You can move a "file pointer" (your needle) to any position in the file and start reading or writing immediately.

Moving the Needle with the File Pointer

The magic happens with the seek(long pos) method. When you call seek(100), you're telling Java, "Move the pointer to the 100th byte from the beginning of the file." Everything you do after that—whether it's reading an integer or writing a string—happens at that specific offset.

I've often seen developers struggle with this because they forget that the pointer moves automatically. If you read a 4-byte integer, your pointer is now 4 bytes further ahead. If you need to go back to where you started, you'll need to call getFilePointer() to keep track of your position or seek() to reset it.


import java.io.*;

public class RecordManager {
    public static void main(String[] args) throws IOException {
        // "rw" means we want both read and write access
        try (RandomAccessFile raf = new RandomAccessFile("inventory.dat", "rw")) {
            // Let's say each item record is exactly 16 bytes
            // We want to jump straight to the 3rd item (index 2)
            raf.seek(2 * 16); 
            
            // Read the ID of the 3rd item (assuming it's an int)
            int itemId = raf.readInt();
            System.out.println("The ID at position 32 is: " + itemId);
            
            // Now, let's update a value at that same spot
            raf.seek(2 * 16); 
            raf.writeInt(999); // Overwriting the ID with 999
        }
    }
}

The Importance of Fixed-Width Records

Here is the catch: RandomAccessFile is only truly powerful if you know exactly where your data starts. If you're storing variable-length strings (like "Apple" then "Watermelon"), you can't simply calculate the offset to the 5th item because you don't know how long the first four were. This is why we use "fixed-width records."

In a real-world system—like a basic database engine—I would define a strict schema. For example: "The first 4 bytes are the ID, the next 20 bytes are the Name (padded with spaces), and the final 4 bytes are the Price." Now, the 10th record is always at 10 * 28 bytes. It makes your file access lightning fast because you skip the "scanning" phase entirely.

Choosing Your Access Mode

When you instantiate a RandomAccessFile, you have to provide a mode string. You'll mostly use "r" for read-only or "rw" for read-write. If you try to write to a file opened with "r", Java will throw an IOException. It's a simple safeguard, but it'll trip you up if you're not paying attention.




📋 Practical Task

Build a Fixed-Length Game High-Score Database

Your task is to create a program that manages a high-score file where each entry has a fixed size. This will simulate how a simple game might save a leaderboard without loading the entire file into memory.

Requirements:

  • Create a RandomAccessFile named scores.bin in "rw" mode.
  • Each record must be exactly 8 bytes: a 4-byte int for the Player ID and a 4-byte int for the Score.
  • Implement a method updateScore(int playerIndex, int newScore) that uses seek() to jump to the specific player's score and overwrite it without touching the rest of the file.
  • Implement a method readScore(int playerIndex) that jumps to the record and returns the score.
  • In your main method, initialize the file with three players, then use your updateScore method to change the second player's score and verify the change with readScore.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.