View RSS Feed

My Java Tips

Randomly Accessing Files

Rate this Entry
by , 11-13-2011 at 11:12 AM (4524 Views)
I have seen a lot of Java guys struggling with accessing a file and playing the data in it. File input output operations are obviously slow as compared to "in memory" operations but then you have persistent data which is of good use. Someone can argue that databases should be used for input and output but then it’s a separate debate. Just to keep it short, I would say that sometimes it is better to use text files for input and out.


In this post, I will write about randomly accessing files, reading and writing data to the files. Java provides a class named RandomAccessFile which is part of java.io package for this purpose.

Following two constructors are available
RandomAccessFile(File file, String mode)
RandomAccessFile(String name, String mode)

So we can create object of RandomAccessFile either my mentioning the filename (with path) or my giving the name of File object. There are 4 different modes which are as follows:
r – to open file for reading
rw . to open file for reading and writing
rws – to open file for reading and writing and also to write every update to file's content or metadata synchronously to the underlying storage device.
rwd - to open file for reading and writing and also to write every update to file's content synchronously to the underlying storage device.

Lets use both the constructors for better understanding.

Java Code:
File file = new File("C:\demo.txt");
RandomAccessFile raf = new RandomAccessFile(file, "rw");


RandomAccessFile raf =
   new RandomAccessFile("C:\demo.txt", "rw");
So far so good. We have RandomAccessFile. Time for a simple example.

demo.txt


Welcome to Java World.

Java Code:
	File file = new File("C:\demo.txt");
        RandomAccessFile raf = new RandomAccessFile(file, "rw");
        byte ch = raf.readByte();
        System.out.println("First character: " + (char)ch);
        raf.seek(0);
        System.out.println("First Line: " + raf.readLine());
        raf.seek(file.length());
        raf.write(0x0A);
        raf.writeBytes("This line is appended by our Java application.");
        raf.close();
Output:


First character: W
First Line: Welcome to Java World.

After execution, demo.txt is altered. The updated file will have following contents:

demo.txt (updat

ed)


Welcome to Java World.
This line is appended by our Java application.

We first created a RandomAccessFile object with read and write mode. We read first character and first line using readByte() and readLine() methods. To move the pointer, seek() method is used. At the end, we wrote a line into the file.

It is assumed that you have gone through the first part (Randomly Accessing Files (1)). In this post, I will write some more examples to show interesting things that can be done using RandomAccessFile object.


An interesting thing that should be kept in mind with dealing with RandomAccessFile object is that there is a pointer that is moved when you read a character, byte or a line. The next read or write operation will occur from the current position of the file pointer. If you wish to move the pointer to a place, you can use seek method.

In the example below, the pointer is moved at the end of the file and current date/time is appended.

Java Code:
File file = new File("C:\demo.txt");
RandomAccessFile raf = new RandomAccessFile(file, "rw");
raf.seek(file.length());
raf.write(0x0A);
raf.writeBytes("File checked at: " +  new Date());
raf.close();
We have the following text file:

demo.txt


Lets learn Java by examples.
Java 6 is the newest one.

We will read the first line, display it on the console and then will add a line to the file.

Java Code:
	 File file = new File("C:\demo.txt");
        RandomAccessFile raf = new RandomAccessFile(file, "rw");
        System.out.println(raf.readLine());
        raf.write(0x0A);
        raf.writeBytes("This line is added by application.");
        raf.close();
Output:


Lets learn Java by examples.

demo.txt (updated)


Lets learn Java by examples.
This line is added by application.

So what we have here. The last line of demo.txt is overwritten by our application. The text was written from the current pointer position and everything from there till the end of written line is overwritten.

Following example shows how to move pointer to a specified place in the file and then read from there.

Java Code:
	File file = new File("C:\demo.txt");
        RandomAccessFile raf = new RandomAccessFile(file, "rw");
        raf.seek(10);
        System.out.println(raf.readLine());
If you want to append a line in between some file text, you have to be very careful. A simple way is to copy and store the text from where you want to write into a StringBuffer, after writing, append the saved text so nothing will be lost. I will write a post on this soon.

Writing to a text file using RandomAccessFile will overwrite the text if the text is written before the end of file. I will present an example to prevent loss of data.
More...
Please go through my previous posts on this topics
- Randomly Accessing Files (1)
- Randomly Accessing Files (2)

We have a Text file with following contents:
demo.txt

If there is a security manager, its checkRead method is called with the pathname of the file argument as its argument to see if read access to the file is allowed.
If the mode allows writing, the security manager's checkWrite method is also called with the path argument to see if write access to the file is allowed.
File ends here.

We want to add “This line is added by application.” Just after the first line. Lets see how to do this.

Java Code:
		File file = new File("C:\demo.txt");
		RandomAccessFile raf = new RandomAccessFile(file, "rw");
		String str = raf.readLine();

		int size = (int)raf.length() - str.length();
		byte[] myByteArray = new byte[size];

		raf.read(myByteArray);
		raf.seek(str.length());
		raf.write(Character.LINE_SEPARATOR);
		raf.writeBytes("This line is added by application.");
		raf.write(Character.LINE_SEPARATOR);
		raf.write(myByteArray);

		raf.close();
demo.txt (updated)
If there is a security manager, its checkRead method is called with the pathname of the file argument as its argument to see if read access to the file is allowed.
This line is added by application.
If the mode allows writing, the security manager's checkWrite method is also called with the path argument to see if write access to the file is allowed.
File ends here.

Required results are achieved. The text is added at the right place without any lose of previous information. How this is done? Let me briefly explain. First I created a RandomAccessFile object with rw mode. The file was opened and its first line was read and stored in a string object. Then we created a byte array with size :

No of characters in the file – No of characters in first line (str)

The file pointer is pointing at the end of first line. We read all the contents from the current position (after first line) and saved them into byte array. Now pointer is pointing to the end of file. Pointer was moved to the end of first line using seek method and the required line was written to the file. And then finally, the byte array containing the text after the first line was written to the file.

Submit "Randomly Accessing Files" to Facebook Submit "Randomly Accessing Files" to Digg Submit "Randomly Accessing Files" to del.icio.us Submit "Randomly Accessing Files" to StumbleUpon Submit "Randomly Accessing Files" to Google

Comments