|
JavaFAQ Home » Java Lessons by Jon Huhtala

Using the RandomAccessFile class
Overview
In the previous lesson, you
learned how to uses Java's I/O streams to write data to disk and read data from
disk. In both cases, the organization of the file was sequential. All file data
was written or read one item after another.
Sequential files are useful, but
they do not provide a way to quickly locate an item of data without reading
through all the other items of data that precede it. They also do not provide a
means of updating an item of data without copying the entire file.
In this lesson, you will learn
the essentials of Java's RandomAccessFile class, which permits a program to directly access
an item of data and replace its contents.
........
Continues on the next page, click link below...
The RandomAccessFile class
- Has two constructors. The most frequently used requires two parameters
-
The reference of a File object that contains the
pathname of the file.
-
A String that represents the mode of access. It
must be either "r"
(read only) or "rw"
(read/write).
For example, if fd is
the reference of a File
object
RandomAccessFile raf = new
RandomAccessFile(fd, "rw"); will construct a RandomAccessFile object for
both reading and writing primitive values and UTF strings to the file. Because
a checked, IOException
may occur, the statement should be enclosed in a try block with an appropriate catch.
- Has many useful methods as follows:
|
Method |
Usage |
|
getFilePointer() |
Returns the byte offset of the pointer
into this file |
|
length() |
Returns the byte length of this
file |
|
readBoolean() |
Reads a boolean value from the pointer location
within the file |
|
readByte() |
Reads a byte value from the pointer location
within the file |
|
readChar() |
Reads a char value from the pointer location
within the file |
|
readDouble() |
Reads a double value from the pointer location
within the file |
|
readFloat() |
Reads a float value from the pointer location
within the file |
|
readInt() |
Reads a int value from the pointer location within
the file |
|
readLong() |
Reads a long value from the pointer location
within the file |
|
readShort() |
Reads a short value from the pointer location
within the file |
|
readUTF() |
Reads a String from the pointer location within
the file according to the UTF standard |
|
seek() |
Sets the pointer offset, measured from the
beginning of this file, at which the next read or write will
occur |
|
writeBoolean() |
Writes a specified boolean value to the
pointer location within the file |
|
writeByte() |
Writes a specified byte value to the
pointer location within the file |
|
writeChar() |
Writes a specified char value to the
pointer location within the file |
|
writeDouble() |
Writes a specified double value to the
pointer location within the file |
|
writeFloat() |
Writes a specified float value to the
pointer location within the file |
|
writeInt() |
Writes a specified int value to the
pointer location within the file |
|
writeLong() |
Writes a specified long value to the
pointer location within the file |
|
writeShort() |
Writes a specified short value to the
pointer location within the file |
|
writeUTF() |
Writes a specified String to the pointer
location within the file according to the UTF
standard |
Notes:
-
All read and write methods
automatically advance the pointer to the next data item within the file.
-
Because a checked, IOException may occur, calls
to these methods should be enclosed in a try block with an appropriate catch. Consult the Java API
documentation for more details.
import java.io.*; public
class App { public static void main(String[] args)
{
// Local variables and object
references.
File fd;
//
Get the path name from the user.
System.out.print("Enter the file's complete path name:
"); fd = new
File(Keyboard.readString());
// Try to process the
file.
try {
//
Format the file with 100 integer values (all
zero).
DataOutputStream out = new
DataOutputStream(new FileOutputStream(fd));
for (int i = 0; i < 100; i++)
{
out.writeInt(0);
}
out.close(); System.out.println("The file is
formatted with 100 integers");
//
Re-open the file for random reading and
writing.
RandomAccessFile raf = new
RandomAccessFile(fd, "rw");
// Allow the
user to see and change any integer value
within // the
file.
char
again; do
{
// Ask the user for the
integer's position within the
file.
System.out.print("Specify an integer's position (0 to 99):
"); int position =
Keyboard.readInt();
//
Calculate the integer's offset (byte displacement)
within // the
file.
int pointer = position
* 4;
// If the offset is
valid, locate the integer, read and
display // its current value,
get a new value from the user, and
write // the new value back to
the same location within the
file.
if (pointer <
raf.length()) {
raf.seek(pointer);
System.out.println("Current value: " +
raf.readInt());
raf.seek(pointer);
System.out.print("New value:
");
raf.writeInt(Keyboard.readInt());
}
// If the offset is not
valid, display an error
message.
else
{
System.out.println("Invalid
position");
}
// Ask the user if they
want to change another integer
value // and repeat the loop as
requested.
System.out.print("Change another value? (Y/N)
"); again =
Keyboard.readChar(); } while (again == 'Y'
|| again == 'y');
// Close the random
access file.
raf.close();
// Re-open the file for
sequential input and display the // file's
contents.
DataInputStream in = new
DataInputStream(new FileInputStream(fd));
try { int position =
0; while (true)
{
System.out.println(position + ": " +
in.readInt());
position++;
} } catch
(EOFException e) {
System.out.println("");
}
in.close(); System.out.println("Closed - " +
fd.getPath()); }
// Catch an
IOException if one is thrown.
catch (IOException e)
{
System.out.println(e.getMessage()); }
} }
Limitations and
solutions
The usefulness of the RandomAccessFile class is severely restricted by its inability to
read and write objects. For example, it would be difficult to use a RandomAccessFile to process a
file of Customer
objects.
The simplest solution to this problem is to use a Map collection (such as a HashMap) for the objects. All collections are
serializable. In a single I/O operation, the entire Map can be written to disk using an ObjectOutputStream or read from
disk using an ObjectInputStream. The get() and put() methods can be used to access the collection's objects while
the Map is in memory.
Lab exercise for Ferris
students
E-mail your answers to this
assignment no later than
the due date listed in the class schedule.
Review questions
-
True or False: The seek() method is overloaded to measure the offset of an item of
data relative to the end of the file.
-
True
-
False
-
Assume that myFile references a RandomAccessFile containing
double values and that an
item of data has just been read. Which one of the following must be coded in
order to sequentially read the next item of data from the file?
-
myFile.seek(RandomAccessFile.NEXT);
-
myFile.seek(myFile.getPointer() + ;
-
myFile.pointer++;
-
myFile.setPointer(myFile.getPointer() + ;
-
none of the above
-
Assume that sFile references a RandomAccessFile of short
values. Which one of the following correctly positions the pointer in order to
read the last short value from the
file?
-
sFile.setPointer(sFile.length() - 2);
-
sFile.setPointer(sFile.length() - 4);
-
sFile.seek(sFile.length() - 2);
-
sFile.seek(sFile.length() - 4);
-
sFile.seek(RandomAccessFile.LAST);
-
If theFile is a File object
containing a path name, code a single statement to construct a RandomAccessFile object named readOnly that only allows data to be read
from the file. Printer Friendly Page
Send to a Friend
..
Search here again if you need more info!
|