FileChannel Objects in Java, Background Information
Java Programming Notes # 1786
The recently released JavaTM 2 SDK, Standard Edition Version 1.4 contains a number of new features.
Among the features which are new to version 1.4 is the concept of an IO channel. Here is part of what Sun has to say about a channel:
"A channel represents an open connection to an entity such as a hardware device, a file, a network socket, or a program component that is capable of performing one or more distinct I/O operations, ..."A channel is not the same as a stream. Streams have been supported by Java since the earliest days of Java. Channels were not introduced until version 1.4.
The java.nio.channels package
Much of the support for channels is provided in the package named java.nio.channels. This package defines more than a dozen new classes, and about seven new interfaces, not counting the new exception classes. (In addition, there are four more new packages that begin with the name java.nio.) Among the more interesting new classes in the java.nio.channels package are the following:
- Pipe.SinkChannel and Pipe.SourceChannel
There is much to learn
As you can readily see from the above list, there is much more to learn about channels than can reasonably be included in a single lesson.
This article is the first in a miniseries that will deal mainly with the FileChannel class. The purpose of this lesson is to introduce you to the concept of channels (and other associated new IO features) from a read/write IO viewpoint.
Future lessons will walk you through sample programs that use FileChannel objects to perform read/write file IO for different primitive data types as well as for data records containing mixed primitive data types.
Future lessons will also provide background material for the use of channels from a memory mapping viewpoint, and will walk you through one or more sample programs that perform memory mapped IO using channels.
As time goes on, I plan to publish additional lessons that will help you learn how to use other new IO features including:
- File locks
- Character-set encoders and decoders
- Pattern matching on files using regular expressions
- Socket channels for both clients and servers
- Non-blocking reads
- Non-blocking servers
You may find it useful to open another copy of this lesson in a separate browser window. That will make it easier for you to scroll back and forth among the different listings and figures while you are reading about them.
I recommend that you also study the other lessons in my extensive collection of online Java tutorials. You will find those lessons published at Gamelan.com. However, as of the date of this writing, Gamelan doesn't maintain a consolidated index of my Java tutorial lessons, and sometimes they are difficult to locate there. You will find a consolidated index at www.DickBaldwin.com.
Before getting into the details of FileChannel objects, I need to tell you that much of what you will see in these lessons will involve objects of classes with names like ByteBuffer, DoubleBuffer, ShortBuffer, etc. These classes extend the Buffer class, and as such inherit a number of methods from the Buffer class. In addition, the subclasses of Buffer provide methods that are appropriate for objects instantiated from the subclasses.
It will be much easier for you to understand this discussion of FileChannel objects if you are already familiar with the features of Buffer and ByteBuffer. I have previously published lessons on these topics entitled Understanding the Buffer class in Java and The ByteBuffer Class in Java. You may find it useful to review these two lessons in preparation for your study of this lesson.
What is a FileChannel?
Sun describes an object of the FileChannel class simply as
"A channel for reading, writing, mapping, and manipulating a file."
In this miniseries, I will show you how to use FileChannel objects for reading files and writing files. I will also show you how to map files into memory.
Tied directly to ByteBuffer
FileChannel objects are tied directly to ByteBuffer objects. As mentioned earlier, the ByteBuffer class extends the Buffer class. Hence, a ByteBuffer object is a Buffer object.
A Buffer object is a "container for data of a specific primitive type."
According to Sun, "Aside from its content, the essential properties of a buffer are its capacity, limit, and position." I discuss those three properties in some detail in the lesson on the Buffer class that I referred to earlier, and won't repeat that discussion here. However, for convenience, I will provide Sun's definition of the position property
"A buffer's position is the index of the next element to be read or written."The sample programs in this miniseries make extensive use of the value of the position property of a buffer.
FileChannel also has a position
Similarly, a FileChannel object also has a current position within its file. The current position of a FileChannel object can be both queried and modified.
Getting the FileChannel position
The current position of a FileChannel object can be queried by invoking the overloaded position() method on the FileChannel object's reference. This method returns the channel's file position. This is a non-negative long integer counting the number of bytes from the beginning of the file to the current position.
Setting the FileChannel position
Similarly, the current position of a FileChannel object can be modified by invoking the overloaded position method on the FileChannel object's reference. This overloaded version of the method requires an incoming integer parameter of type long and sets a new position for the channel.
Be careful when setting the position
Care must be exercised when setting a new position for the channel. For example, here is what Sun says will happen if the new position is greater than the file's current size:
"Setting the position to a value that is greater than the file's current size is legal but does not change the size of the file. A later attempt to read bytes at such a position will immediately return an end-of-file indication. A later attempt to write bytes at such a position will cause the file to be grown to accommodate the new bytes; the values of any bytes between the previous end-of-file and the newly-written bytes are unspecified."The physical file
The physical file associated with the FileChannel object contains a variable-length sequence of bytes. These bytes can be read and written. In addition, the current size of the file can be obtained by invoking the size method on the FileChannel object's reference. This method returns the current size of the physical file associated with the channel, measured in bytes as a long integer.