Main Page

Previous Next

File Channel Read Operations

You obtain a reference to a FileChannel object that you can use to read a file by calling the getChannel() method of a FileInputStream object. Since a FileInputStream object opens a file as read-only, only channel read operations are legal. The channel returned by a FileInputStream object has three basic read operations available, each of which read starting at the byte indicated by the current position in the file. The file position will be incremented by the number of bytes read. The three read() methods for a FileChannel object are:

read(ByteBuffer buf)

Tries to read buf.remaining() bytes (equivalent to limit-position bytes) from the file into the buffer, buf, starting at the buffer's current position. The number of bytes read is returned as type int, or -1 if the channel reaches the end-of-file. The buffer position will be incremented by the number of bytes read and the buffer's limit will be left unchanged.

read(ByteBuffer[] buffers)

Tries to read bytes into each of the buffers in the buffers array in sequence. Bytes will be read into each buffer starting at the point defined by that buffer's position. The number of bytes read into each buffer is defined by the remaining() method for that buffer. The read() method returns the total number of bytes read as type int, or -1 if the channel reaches the end-of-file. Each buffer's position will be incremented by the number of bytes read into it. Each buffer's limit will be unchanged.

read(ByteBuffer[] buffers,

int offset,

int length)

This operates in the same way as the previous method except that bytes are read starting with the buffer buffers[offset], and up to and including the buffer buffers[offset+length-1]. This method will throw an exception of type IndexOutOfBoundsException if offset or offset+length-1 are not valid index values for the array buffers.

As you can see, all three read() methods read data into one or more buffers of type ByteBuffer. Since you can only use ByteBuffer objects to receive the data read from the file, you can only read data from a file via a channel as a series of bytes. How you interpret these bytes afterwards though is up to you.

All three methods can throw exceptions of any of the following types: :

NonReadableChannelException

Thrown if the file was not opened for reading.

ClosedChannelException

Thrown if the channel is closed.

AsynchronousCloseException

Thrown if the channel is closed by another thread while the read operation is in progress.

ClosedByInterruptException

Thrown if another thread interrupts the current thread while the read operation is in progress.

IOException

Thrown if some other I/O error occurs.

The first of these is a subclass of RuntimeException so you are not obliged to catch this exception. If you don't need to identify the other exceptions individually, you can use a single catch block for exceptions of type IOException to catch any of them.

The FileChannel object keeps track of the file's current position, and this is initially set to zero, corresponding to the first byte available from the file. Each read operation increments the channel's file position by the number of bytes read, so the next read operation will start at that point, assuming you have not modified the file position by some other means. When you need to change the file position in the channel – to reread the file for instance – you just call the position()method for the FileChannel object, with the index position of the byte where you want the next read to start as the argument to the method. For example, with a reference to a FileChannel object stored in a variable inChannel, you could reset the file position back to the beginning of the file with the statements:

try {
  inChannel.position(0);   // Set file position to first byte

} catch(IOException e) {
  e.printStackTrace();
}

This method will throw a ClosedChannelException if the channel is closed, or an IOException if some other error occurs, so you need to put the call in a try block. It can also throw an IllegalArgumentException if the argument is negative. This is a subclass of RuntimeException You can legally specify a position beyond the end of the file, but a subsequent read operation will just return -1 indicating the end-of-file has been reached.

Calling the position() method with no argument specified returns the current file position. This version of the method can also throw exceptions of type ClosedChannelException and IOException so you must put the call in a try block or make the calling method declare the exceptions in a throws clause.

Click To expand

The amount of data read from a file into a byte buffer is determined by the position and limit for the buffer when the read operation executes. Bytes are read into the buffer starting at the byte in the buffer given by its position, and assuming there are sufficient bytes available from the file, limit-position bytes will be stored in the buffer.

We will see some other channel read() methods later that we can use to read from a particular point in the file.

Previous Next
JavaScript Editor Java Tutorials Free JavaScript Editor