FileChannel Objects in Java, Background Information, Page 3
The state of a FileChannel object
The state of a FileChannel object is connected to that of the object whose getChannel method returned the reference to the FileChannel object.
Normally, changing the channel's position, whether explicitly or by reading or writing bytes, will change the file position of the originating object, and vice versa. (An exception to this rule will be discussed shortly.)
Similarly, changing the file's length via the file channel will change the length seen via the originating object, and vice versa. Changing the file's content by writing bytes will change the content seen by the originating object, and vice versa.
The fourth overloaded read method
The fourth overloaded read method of the FileChannel class has the following signature:
read(ByteBuffer dst, long position)This method reads a sequence of bytes from the channel into the given buffer, starting at the specified file position. (This is the exception to the norm mentioned above.)
This method works the same as the read(ByteBuffer) method, except that bytes are read starting at the specified file position rather than at the channel's current position. Furthermore, this method does not modify the channel's position. If the specified position is greater than the file's current size then no bytes are read.
A fourth overloaded write method
A similar overloaded write method having the signature shown below works the same as the write(ByteBuffer) method. Again, however, there is an exception to the normal operation described earlier. In this case, bytes are written starting at the specified file position rather than at the channel's current position.
write(ByteBuffer src, long position)This method does not modify the channel's position. If the specified position is greater than the file's current size then the file will be extended to accommodate the new bytes. Note, however, that the values of any bytes between the previous end-of-file and the newly-written bytes are unspecified.
Open for reading and writing
As I mentioned earlier, you can get a FileChannel object that is connected to an underlying file by invoking the getChannel method on an existing FileInputStream, FileOutputStream, or RandomAccessFile object.
A FileChannel object obtained from a FileInputStream object will be open for reading, but not for writing. A FileChannel object obtained from a FileOutputStream object will be open for writing, but not for reading.
Finally, a FileChannel object obtained from a RandomAccessFile object will be open for reading if the object was created in the "r" mode, and will be open for reading and writing if the object was created in the "rw" mode.
If you create an instance of a FileOutputStream object using the following constructor (passing true as a parameter), the file will be opened in append mode.
If you get a file channel from that object, the file channel will also be opened in append mode.
According to Sun,
"In this mode each invocation of a relative write operation first advances the position to the end of the file and then writes the requested data."
Also according to Sun,
"Whether the advancement of the position and the writing of the data are done in a single atomic operation is system-dependent and therefore unspecified."
A FileChannel object is a channel for reading, writing, mapping, and manipulating a file.
FileChannel objects are tied directly to ByteBuffer objects. Therefore, you must understand the use of the Buffer class and its subclasses in order to understand the use of the FileChannel class.
A Buffer object is a container for data of a specific primitive type.
The essential properties of a buffer are its capacity, limit, and position.
A buffer's position is the index of the next element to be read or written.
A FileChannel object also has a current position within its file, which can be both queried and modified.
Care must be exercised when setting a new position for a FileChannel object.
The physical file associated with the FileChannel object contains a variable-length sequence of bytes, which may be read and written.
The size of the physical file can be increased or reduced through truncation.
The FileChannel class implements several interfaces, including the ByteChannel interface.
The ByteChannel interface requires that the FileChannel class implement the following methods:
- read(ByteBuffer dst)
- write(ByteBuffer src)
Any class that implements an interface must provide a concrete definition for all the interface methods. In addition, classes that implement the ByteChannel interface are expected to provide certain specific behavior for the read, write, and close methods.
Channels can be operated in a blocking or a non-blocking mode.
In addition to the read, write, and close methods applicable to all classes that implement the ByteChannel interface, the FileChannel class defines several file-specific operations.
According to Sun, "File channels are safe for use by multiple concurrent threads."
In addition to the ByteChannel interface, the FileChannel class implements the ScatteringByteChannel interface and the GatheringByteChannel interface (plus several other interfaces as well).
The FileChannel class provides four overloaded versions of the read method, only one of which is declared in the ByteChannel interface.
Likewise, the FileChannel class provides four overloaded versions of the write method, only one of which is declared in the ByteChannel interface.
Thus, the FileChannel class provides file-specific read and write capability over and above that declared in the ByteChannel interface.
Two of the four overloaded read methods are declared in the ScatteringByteChannel interface. Two of the overloaded write methods are declared in the GatheringByteChannel interface.
A scattering read operation reads, in a single invocation, a sequence of bytes into one or more of a given sequence of buffers.
A gathering write operation writes, in a single invocation, a sequence of bytes from one or more of a given sequence of buffers.
The fourth overloaded read method of the FileChannel class works the same as the read(ByteBuffer) method, except that bytes are read starting at a specified file position.
The fourth overloaded write method of the FileChannel class works the same as the write(ByteBuffer) method except that bytes are written starting at a specified file position.
The FileChannel class does not define methods for opening existing files or for creating new ones.
You can get a FileChannel object by invoking the getChannel method on an existing file IO stream object.
A FileChannel object can be opened for reading, for writing, or for both reading and writing.
A FileChannel object can also be opened for writing in append mode.
Future lessons in this miniseries 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.
For data of type byte, you will see the connection that exists between the physical file, the FileChannel object, and a ByteBuffer object.
For data of type double, you will see the connection that exists between the physical file, the FileChannel object, a ByteBuffer object, and a DoubleBuffer object that provides a double view of data stored in the ByteBuffer object.
For data of type short, you will see the connection that exists between the physical file, the FileChannel object, a ByteBuffer object, and a ShortBuffer object that provides a short view of data stored in the ByteBuffer object.
You will learn that view objects such as DoubleBuffer and ShortBuffer are available for all the primitive types other than boolean.
Thus, in addition to learning about FileChannel objects, you will also learn about some additional interesting aspects of the subclasses of the Buffer class.
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.
Copyright 2002, Richard G. Baldwin. Reproduction in whole or in part in any form or medium without express written permission from Richard Baldwin is prohibited.Richard Baldwin is a college professor (at Austin Community College in Austin, TX) and private consultant whose primary focus is a combination of Java, C#, and XML. In addition to the many platform and/or language independent benefits of Java and C# applications, he believes that a combination of Java, C#, and XML will become the primary driving force in the delivery of structured information on the Web.
Richard has participated in numerous consulting projects, and he frequently provides onsite training at the high-tech companies located in and around Austin, Texas. He is the author of Baldwin's Programming Tutorials, which has gained a worldwide following among experienced and aspiring programmers. He has also published articles in JavaPro magazine.
Richard holds an MSEE degree from Southern Methodist University and has many years of experience in the application of computer technology to real-world problems.