Java Reference
In-Depth Information
Your Java program interacts with a channel for an I/O operation using byte buffers. That is, even if you have many
different kinds of buffers, you will need to convert them to a byte buffer before you can pass them to a channel for
reading/writing data.
A
ReadableByteChannel
is used to read data from a data source into a byte buffer using its
read()
method.
A
WritableByteChannel
is used to write data from a byte buffer to a data sink using its
write()
method. A
ByteChannel
is capable of both reading and writing byte data using its
read()
and
write()
methods, respectively.
A
ScatteringByteChannel
reads data from a data source into multiple byte buffers. It is useful to read data from a
known file format or a similar data source, where data is supplied in some fixed-length headers followed by a variable
length body. For example, suppose a file has a 256-byte fixed-length header and a variable length body. An object
of the
ScatteringByteChannel
class is used to read data from this kind of file using two byte buffers. The first byte
buffer will be of capacity 256. The second buffer will be of a size of your choice. When you pass these two buffers to
this channel, the fixed-length header of 256 bytes will be read in the first buffer. The second buffer will have the file
data and you may have to use the second buffer multiple times to read the rest of bytes from the file. The advantage of
using this channel is separating the fixed-length header data from other data.
A
GatheringByteChannel
performs just the opposite of what a
ScatteringByteChannel
performs. It writes data
from multiple byte buffers to a data sink. It is used to write data in a format that is grouped in some fixed-length
headers, followed by a variable length body.
An
InterruptibleChannel
channel can be closed asynchronously. If a thread is blocked on an I/O operation
on this channel, another thread can call its
close()
method to close it. The blocked thread will receive an
AsynchronousCloseException
. If a thread is blocked on an I/O operation on this channel, another thread can
call the
interrupt()
method on the blocked thread. This channel is closed, and the blocked thread receives a
ClosedByInterruptException
exception.
Typically, you do not deal with these channel interfaces directly in your Java program. You will be dealing with
concrete channel classes that implement one or more of these interfaces. Unlike streams, you do not create a channel
directly. You get it indirectly by calling a method. To obtain a channel for a data source and a data sink, you will need
to create an object of
InputStream
and
OutputStream
using old ways of working with I/O using classes in the
java.io
package. The
Channels
class in the
java.nio.channels
package is a utility class that has many
static
methods to
convert streams into channels and vice versa. The
Channels
class also provides methods to convert readers/writers
to channels and vice versa. For example, if you have an input stream object named
myInputStream
, you can obtain a
ReadableByteChannel
as follows:
// Get a ReadableByteChannel from an InputStream
ReadableByteChannel rbc = Channels.newChannel(myInputStream);
If you have a
ReadableByteChannel
named
rbc
, you can obtain the underlying
InputStream
object as follows:
// Get the InputStream of the ReadableByteChannel
InputStream myInputStream = Channels.newInputStream(rbc);
For NIO, the
FileInputStream
and
FileOutputStream
classes have been modified to work with channels. They
have a new method called
getChannel()
to return a
FileChannel
object. A
FileChannel
is used to read and write data
to a file. The
FileChannel
object obtained from a
FileInputStream
is opened in a read-only mode. A
FileChannel
object obtained from a
FileOutputStream
object is opened in a write-only mode. If you obtain a
FileChannel
from a
RandomAccessFile
, it is opened in a read-only, write-only, or read-write mode, depending on the way you create that
RandomAccessFile
object. The following snippet of code obtains
FileChannel
objects for different kinds of file streams:
FileInputStream fis = new FileInputStream("luci1.txt");
FileChannel fcReadOnly = fis.getChannel(); // A read-only channel
FileOutputStream fos = new FileOutputStream("luci1.txt");
FileChannel fcWriteOnly = fos.getChannel(); // A write-only channel