CHAPTER 21-4
RANDOM ACCESS FILES
Sequential access files vs Random access files
A sequential access file has a file pointer associated with it, which programmers cannot directly access.
When we read from a sequential file, we read the data stored in the location _____________________.
When we write to a sequential file, we write our data to the location _____________________. The
file pointer position is automatically advanced after each read or write operation by the size of the data
just retrieved or written.
A sequential access file can be used for reading or writing, but not both. When we open a sequential
access file to read, the file pointer is initialized to _____________________. When we open a
sequential access file to write, the file pointer is initialized to _____________________. When we
open a sequential access file to append, the file pointer is initialized to _____________________.
Consequently, when we open a sequential access file and want to read the 100th record, the program
must first read _____________________ to position the file pointer at the 100th record. The situation
is worse when we want to update the 100th record in a sequential access file.
Random access files allow reading and writing to the same file simultaneously. In addition, random
access files allow us to access a particular record directly without accessing all of the preceding
records.
Random access files are also called direct access files.
Class RandomAccessFile
Class RandomAccessFile implements both the DataInput interface and the DataOutput interface.
Thus, it supports the same set of read methods as DataInputStream (e.g. readDouble, readUTF) and the
same set of write methods as DataOutputStream (e.g. writeDouble, writeUTF). Note that class
RandomAccessFile does not support writeObject.
A RandomAccessFile file is a binary file.
------------------------------------------------------------------------------------------------------------------Usage: public RandomAccessFile(String name, String mode) throws FileNotFoundException
Post:
This RandomAccessFile initialized to read from, and optionally to write to, the file specified by
the first argument. The argument mode can be:
"r" -- Opens the file for reading only. It throws FileNotFoundException if the file does not
exist or cannot be opened for any reason. Invoking any of the write methods of the resulting
object will cause an IOException to be thrown.
"rw" -- Opens the file for reading and writing. If the file does not already exist then an attempt
will be made to create it. It throws FileNotFoundException if the file exists but is a directory
rather than a regular file, or cannot be opened or created for any other reason.
In either case, the file pointer is set at the beginning.
Throws: FileNotFoundException as described.
Usage: public void seek(long pos) throws IOException
Post:
The file pointer position set to pos, measured in bytes from the beginning of this file, at which the
next read or write occurs. The offset may be set beyond the end of the file. Setting the offset
beyond the end of the file does not change the file length. The file length will change only by
writing after the offset has been set beyond the end of the file.
Throws: IOException if pos is less than 0 or if an I/O error occurs.
Usage: public long length() throws IOException
Return: The length of this file in bytes.
Throws: IOException if an I/O error occurs.
Usage: public void setLength(long len) throws IOException
Post:
The length of this file set to len bytes. If the present length of the file is greater than len then the
file will be truncated. If the present length of the file is smaller than len then the file will be
extended. In this case, the contents of the extended portion of the file are not defined. In either
case, the file pointer is set to len.
Throws: IOException if an I/O error occurs.
Usage: public long getFilePointer() throws IOException
Return: The offset from the beginning of the file, in bytes, at which the next read or write occurs.
Throws: IOException if an I/O error occurs.
------------------------------------------------------------------------------------------------------------------Figure 21-4-1. Some useful methods of class RandomAccessFile.
//Example 21-4-1
import java.io.*;
class Demo
{
public static void main(String[] args) throws IOException
{
RandomAccessFile s=new RandomAccessFile("number.data", "rw");
s.setLength(0);
s.writeInt(1);
s.writeInt(2);
s.writeInt(3);
s.seek(4);
//line 11
s.writeInt(99);
//line 12
s.seek(s.length());
//line 13
s.writeInt(88);
//line 14
s.seek(0);
System.out.println(s.readInt());
System.out.println(s.readInt());
System.out.println(s.readInt());
System.out.println(s.readInt());
s.close();
}
}
A fixed-length record
Typically, all records stored in a random access file belong to the same record type. In addition, in
order for a program to locate the nth record in a random access file easily, we typically require that all
records in a random access file be of the same length (a variable length data type such as String would
not be appropriate in such a record type).
//Example 21-4-2
import java.io.*;
public class Student
{
private static final int NAMEMAX=25;
private int id;
private char[] name=new char[NAMEMAX];
private int age;
public Student()
{
id = -1;
for (int j= 0; j< NAMEMAX; ++j)
name[j]=' ';
age = -1;
}
public Student (int id, String s, int age)
{
this.id = id;
for (int j=0; j<s.length(); ++j)
{
if (j<NAMEMAX) name[j]=s.charAt(j);
else break;
}
for (int j= s.length(); j< NAMEMAX; ++j)
name[j]=' ';
this.age = age;
}
public void setId(int s)
{
id = s;
}
public int getId()
{
return id;
}
public void setName(String s)
{
for (int j=0; j<s.length(); ++j)
{
if (j<NAMEMAX) name[j]=s.charAt(j);
else return;
}
for (int j= s.length(); j< NAMEMAX; ++j)
name[j]=' ';
}
public String getName()
{
String s=new String(name);
return s.trim();
//line 34
}
public void setAge( int a )
{
age = a;
}
public int getAge()
{
return age;
}
public void write(RandomAccessFile f) throws IOException
{
f.writeInt(id);
for (int j= 0; j< NAMEMAX; ++j)
f.writeChar(name[j]);
f.writeInt(age);
}
public void read( RandomAccessFile f ) throws IOException
{
id = f.readInt();
for (int j= 0; j< NAMEMAX; ++j)
name [j] = f.readChar();
age = f.readInt();
}
public static int size()
{
return 58; //4 (int) + 4 (int) + 50 (25 Unicode characters)
}
}
Maintaining a file of fixed-length records
To make the database program we are going to write efficient, we will assume that there are at most
100 students, and their ID numbers are integers in the range 1-100. Since there are at most 100
students, we reserve one empty location in the file for each potential student. Thus, we will create an
initial random access file with 100 empty student records. The first record is reserved for student 1,
the second record is reserved for student 2, and so on.
//Example 21-4-3
import java.io.*;
public class Demo
{
public static void main( String args[] )
{
try
{
Student blank= new Student();
RandomAccessFile f = new RandomAccessFile("students.data", "rw");
for ( int i = 0; i < 100; i++ )
blank.write(f);
}
catch(FileNotFoundException e)
{
System.out.println("File is a directory or cannot be created. Program aborted.");
}
catch(IOException e)
{
System.out.println("Error writing file. Program aborted.");
}
}
}
//Example 21-4-4
import java.io.*;
public class Demo
{
public static void main(String[] args) throws IOException
{
RandomAccessFile f=new RandomAccessFile("students.data", "rw");
Student r=new Student();
r.setId(2);
r.setName("John Johnson");
r.setAge(42);
f.seek((long)((2-1)* Student.size()));
r.write(f);
r.setId(4);
r.setName("Paul Paulson");
r.setAge(22);
f.seek((long)((4-1)* Student.size()));
r.write(f);
f.close();
}
}
//Example 21-4-5
import java.io.*;
import java.util.Scanner;
public class Demo
{
public static void main(String[] args) throws IOException
{
Scanner keyboard=new Scanner(System.in);
RandomAccessFile f=new RandomAccessFile("students.data", "rw");
Student r=new Student();
while (true)
{
System.out.print("Enter ID 1-100 (0 to end): ");
int n=keyboard.nextInt();
if (n<=0 || n>100) break;
f.seek((long)((n-1)*Student.size()));
r.read(f);
System.out.println(r.getId());
System.out.println(r.getName());
System.out.println(r.getAge());
}
}
}
Programming Assignment
Modify the programming assignment from handout 21-2 as follows:
a. Use RandomAccessFile instead of DataInputStream and DataOutputStream.
b. Assume that there are at most 100 students, and their ID numbers are integers in the range 1-100.
Since there are at most 100 students, we reserve one empty location in the file for each potential
student. The first record is reserved for student 1, the second record is reserved for student 2, and
so on
c. Modify class Student so that each student record has 4 fields: id (int), name (at most 30
characters), age (int), major (at most 30 characters).
d. The program should offer the following options to the user:
1. Add new student record
2. Remove student record
3. Update student record
4. Display student record
5. Display all student records
6. Exit
Note:
You do not need to do exception handling. You can assume all inputs are legal. You do have to
make the output well organized and readable. For example, if the user wants to delete a
nonexistent student, the program should output meaning messages.
You cannot read the entire file into a vector. You must process the file directly.
You basically are combining Example 21-4-2, Example 21-4-3, Example 21-4-4, Example 21-4-5,
and the programming assignment from handout 21-2 together with some modifications (for
example, we do not need methods loadStudent and storeStudent).
Hand in/email:
StudentDB.java that contains class Student and class StudentDB
© Copyright 2026 Paperzz