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.
![]() |
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); } }
![]() |
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.