In this techincal tip, let us see how to access the contents of a file randomly instead of the traditional sequential access. Imagine that we want to search for a particular record in a file. If we prefer Sequential access in this case, then it will involve traversing over the file byte by byte and searching for the relevant record. This won’t be an ideal solution particularly if the size of the file is too big. So a mechanism must be there to randomly access the file contents in which case we can use java.io.RandomAccessFile
class. The following code tries to open a file for random accessing,
also read:
- Java Tutorials
- Java EE Tutorials
- Design Patterns Tutorials
- Java File IO Tutorials
RandomAccessFile file = new RandomAccessFile("employees.txt", "rw");
The first argument passed to the RandomAccessFile constructor is the name of the file name and the second argument specifies the mode in which we want to operate on the open file. Passing "rw" means to open the file in read as well as in write mode. The following code snippet shows how to write some contents within the file.
RandomAccessFile file = new RandomAccessFile("employees.txt", "rw"); writeEmployee(file, "John", 35, 54544.43d); writeEmployee(file, "Jenny", 28, 34544.42d); writeEmployee(file, "Joesph", 41, 64544.77d); file.close();
In the above code snippet we are trying to write some information (name, age and salary) about employee object. Here is the definition of the writeEmployee()
method,
static void writeEmployee(RandomAccessFile file, String name, int age, double salary) throws Exception{ file.writeUTF(name); file.writeInt(age); file.writeDouble(salary); }
The methods RandomAccessFile.writeUTF()
, RandomAccessFile.writeInt()
and RandomAccessFile.writeDouble()
are used to write string, integer and double data-types respectively. Now, let us look in the following section how to read the written contents back from the file,
static void readEmployee(RandomAccessFile file) throws Exception{ String name = file.readUTF(); int age = file.readInt(); double salary = file.readDouble(); System.out.println("Name = " + name + ", Age = " + age + ", Salary = " + salary); }
Till now, we have seen how to write and read sequentially using the RandomAccessFile
object. Now, let us see the random access way using the methods getFilePointer()
and seek()
. The method getFilePointer()
returns the current position of the file pointer. Consider the following code snippet,
RandomAccessFile file = new RandomAccessFile("junk.txt", "rw"); file.writeInt(20); System.out.println(file.getFilePointer()); file.writeDouble(12345.5454d); System.out.println(file.getFilePointer()); file.close();
We try to write an integer into the file. Since the size of an integer is 4 bytes, the file pointer would be 4 bytes away from the beginning of the file. So, the call to getFilePointer()
will return 4. In the next statement, we tried to write some double value into the file and since its size is 8, the file pointer would have got traversed to 4 + 8 = 12. So the call to getFilePointer()
will now return 12.
Now let us see the usage of the seek()
method. Consider the following code snippet which writes even numbers into the file.
RandomAccessFile file = new RandomAccessFile("evennumbers.txt", "rw"); int evenNums[] = {0, 2, 4, 7, 10}; for(int evenNum : evenNums){ file.writeInt(evenNum); } file.close();
In the above code, we have stored the even numbers ranging between 0 and 10 in an array and then written them into a file using the enhanced for loop. Purposely, we have written the number 7 (which is not an even number) into the file. Let us correct this by making use of the seek() method. We know that writing an integer into the file will occupy 4 bytes and the number 7 is written after 3 * 4 = 12 bytes. The following code snippet forwards the file pointer to 12 bytes by using the seek()
method and replaces the integer 7 with 8. Then it traverses over the file to read and print the contents to verify the new updated content.
RandomAccessFile file = new RandomAccessFile("evennumbers.txt", "rw"); // Forward the file pointer to 6 bytes file.seek(12); // and write the content. file.writeInt(8); file.seek(0); for(int index = 0; index < 5; index ++){ System.out.println(file.readInt()); } file.close();