Logout

Random Access Files Basics

Recall the difference between saving stuff in RAM as we run a program, versus storing stuff permanently in a file. So, for example, with an array that we create in a program, it exists only within the scope of the program in which it is running while that program is running. So if we want to save data permanently, we need to send it to a file, which gets stored to a permanent storage device such as a hard drive.

During the "revolution" part of the Java Revolution, we looked at the various kinds of files, noting in particular the difference between sequential access and direct access, as well as the concept of indexed files. And you'll recall that we have used the FileWriter class before for storing data.

So now we take what we know as advantages to direct access files, and actually learn a Java implementation of one. The class we will use is called RandomAccessFile. By "RandomAccess", what is meant is actually direct access. As with "Random Access Memory" (RAM), the term makes more sense to us if we think of it as direct access, but we'll just have to live with the term random, meaning direct.

With an array in RAM, it is easy to directly access an element number, once we know which element number we want. So in a binary search for example, we can quite quickly come up with a desired element number, and then directly access the information stored there, without having to sequentially look through all of the elements of the array until we find what we're looking for. We'd like to have the same sort of direct access abilities with a file, and this is particularly important with reading from many permanent storage devices, since they are much slower than reading from RAM.

Before getting into how to directly access from an "RAF" (RandomAccessFile) file, here are the basic commands we'll be using. The following program simply writes a couple of Strings to the file, and then reads them.

   import java.io.*;

   .... 
   
   private RandomAccessFile raf = new RandomAccessFile("file1.txt", "rw"); //This line makes the new file called file1.txt.
   
   private void testingButton() {                                            
        try {
            raf.seek(0);
            raf.writeUTF("hello");
            raf.writeUTF("world");
        } catch (...) {
            ...
        }
    } //So when this button is pressed, two Strings are saved to the file: hello, and world.                                         

    private void readButton() {                                         
        try {
            raf.seek(0);
            String stuffRead = raf.readUTF() + raf.readUTF();
            stuffReadLabel.setText(stuffRead);
            raf.close();
        } catch (...) {
           ... 
        }

    } //So this will print out helloworld in the stuffReadLabel.

So we see there are only five methods required, including the constructor:

RandomAccessFile(String, String) - The constructor takes in two Strings. The first is the file name. The file will be saved by default in the same directory as where your Netbeans project is. The second String defines the "permissions" of the file. "rw" means it is "read" and "write". This means we can read from it, and also we can make changes to it; i.e. write to it.

seek(int) - This method moves the "pointer" a certain number of bytes along. The pointer really isn't a variable per se which we can see in our code; it's just the location in the file which is ready to be read next. So seek(0) means we are ready to start reading at the beginning of the file.

writeUTF(String) - UTF is a UNICODE 16-bit character, and writeUTF will allow us to write a series of UTF characters to the file. So you can think of it as writing one String to a file. The file will be able to keep track of which was the first and which was the last character of the UTF written with any given writeUTF statement.

readUTF() - Reads one UTF String which has been written to the file. So that String is defined by whatever was input by each successive writeUTF line when the file was written to. readUTF returns a String.

close() - When working with only one file this is not necessary to write, but is good practice non-the-less.