Saturday, May 5, 2012

JDK7: Using buffered IO for files in java

If you have read my previous article about NIO.2 "The power of java 7 NIO.2 (JSR 203) (important concepts)" you will get the full understanding and an overall idea about the new NIO.2 features including the buffered files operations.

Buffered IO provides a more efficient technique for accessing files. Two methods of the java.nio.file package's Files class return either a java.io package BufferedReader or a BufferedWriter object. These classes provide an easy to use and efficient technique for working with text files.

We will illustrate the read operation first. In the There's more section, we will demonstrate how to write to a file.

Getting ready
-----------------
To read from a file using a BufferedReader object:

1. Create a Path object representing the file of interest
2. Create a new BufferedReader object using the newBufferedReader method
3. Use the appropriate read method to read from the file

How to do it...
-------------------
1. Create a new console application using the following main method. In this method, we will read the contents of the computers.txt file and then display its contents.

2. Execute the application. Your output should reflect the contents of the computers.txt file, which should be similar to the following:

Apple
Dell
Sony
Toshiba
IBM
Asus


How it works...
-------------------
A Path object representing the computers.txt file was created followed by the creation of a Charset. The ISO Latin Alphabet No. 1 was used for this example. Other character sets can be used, depending on the platform used.

A try-with-resource block was used to create the BufferedReader object. This type of try block is new to Java 7.

This will result in the BufferedReader object automatically being closed when the block completes.

The while loop reads each line of the file. and then displays each line to the console. Any IOExceptions is thrown as needed.

There's more...
-------------------
When a byte is stored in a file, its meaning can differ depending upon the intended encoding scheme. The java.nio.charset package's Charset class provides a mapping between a sequence of bytes and 16-bit Unicode code units. The second argument of the newBufferedReader method specifies the encoding to use. There is a standard set of character sets supported by the JVM, as detailed in the Java documentation for the Charset class.

We also need to consider:
• Writing to a file using the BufferedWriter class.
• Unbuffered IO support in the Files class.
• Writing to a file using the BufferedWriter class.

The new BufferedWriter method opens or creates a file for writing and returns a BufferedWriter object. The method requires two arguments, a Path object and a specified Charset, and can use an optional third argument. The third argument specifies an OpenOption. If no option is specified, the method will behave as though the CREATE, TRUNCATE_EXISTING, and WRITE options were specified, and will either create a new file or truncate an existing file.

In the following example, we specify a new String object containing a name to add to our computers.txt file. After declaring our Path object, we use a try-with-resource block to open a new BufferedWriter.

In this example, we are using the default system charset and StandardOpenOption.APPEND to specify that we want to append the name to the end of our users.txt file. Within the try block, we first invoke the newline method against our BufferedWriter object to ensure that our name goes on a new line. Then we invoke the write method against our BufferedWriter object, using our String as the first argument, a zero to denote the beginning character of the String, and the length of our String to denote that the entire String should be written.

If you examine the contents of the computers.txt file, the new name should be appended to the end of the other names in the file.

Un-buffered IO support in the Files class
--------------------------------------------------
While un-buffered IO is not as efficient as buffered IO, it is still useful at times. The Files class provides support for the InputStream and OutputStream classes through its new InputStream and new OutputStream methods. These methods are useful in instances where you need to access very small files or where a method or constructor requires an InputStream or OutputStream as an argument.

In the following example, we are going to perform a simple copy operation where we copy the contents of the computers.txt file to a newComputers.txt file. We first declare two Path objects, one referencing the source file, computers.txt, and one specifying our destination file, newComputers.txt. Then, within a try-with-resource block, we open both an InputStream and an OutputStream, using the new InputStream and new OutputStream methods. Within the block, we read in the data from our source file and write it to the destination file.

Upon examining the newComputers.txt file, you should see that the content matches that of the computers.txt file.