Team LiB
Previous Section Next Section

Optimize Your Connections

When you work with regular expressions, use FileChannels over other means of accessing a file. That is, instead of using a RandomAccessFile, a FileInputStream, or a FileOutputStream, gain access to your file using a FileChannel.

Although a detailed discussion of FileChannels is beyond the scope of this book, I do want to briefly touch upon them. FileChannels are Java's latest effort at high-performance file input/output (I/O), and they seem to be very successful. Under the covers, they're optimized for whatever operating system you happen to be on, so they're at least as fast and efficient as their java.io.* counterparts—as a matter of fact, they're often much faster. They also offer tools such as FileLocks, the ability to position anywhere in the file, the ability to read and write concurrently, and the ability to map directly to memory buffers.

Note 

FileChannels also interact better with Threads, but that's a completely different topic that's beyond the scope of this discussion.

FileChannels work by reading data at the byte level and storing it into a ByteBuffer. Thus, the code to read the contents of a file by using a FileChannel might look like Listing 4-1. To learn more about ByteBuffers and Channels in general, please consult Sun's documentation.

Listing 4-1: Using FileChannels to Access a File
Start example
import java.io.*;
import java.nio.*;
import java.nio.channels.*;

/**
* Provides an easy mechanism for extracting the regex contents
* of a file
*/
public class FileChannelExample{
    public static void main(String args[]) throws IOException{
        //open a connection to the source code for this
        //class
        FileInputStream fis =
        new FileInputStream("FileChannelExample.java");
        //get a file channel
        FileChannel fc = fis.getChannel();

        //create a ByteBuffer that is large enough
        //and read the contents of the file into it
        ByteBuffer bb = ByteBuffer.allocate((int)fc.size());

        fc.read(bb);
        bb.flip();

        //save the content of the file as a String
        String fileContent= new String(bb.array());

        //release the FileChannel
        fc.close();
        fc = null;

        //write out the contents of this file
        System.out.println("fileContent = " + fileContent);
    }
}
End example

The process is very simple and offers a great many advantages over conventional file access. Basically, you open obtain a FileChannel, read its content into a ByteBuffer or one of its child classes, and then examine that buffer. This is fairly easy to follow in Listing 4-1, because the relevant sections of the code appear in bold. As you can see, if you need to, you can easily convert that data into a String. The advantages you're most concerned with here, of course, relate to speed and memory usage, but there are lot of other, nonregex reasons to use FileChannels.


Team LiB
Previous Section Next Section