Java Reference
In-Depth Information
As you can see, everything remaining in the buffer, which will be elements from the buffer's position up
to but not including the buffer's limit, is copied to the beginning of the buffer. The position is then set to
the element following the last element copied and the limit is set to the capacity. This is precisely what
you want when you have worked part way through the data in an input buffer and you want to add
some more data from the file. Compacting the buffer sets the position and limit such that the buffer is
ready to receive more data. The next read operation using the buffer will add data at the end of what
was left in the buffer.
Any time we are processing an element from the buffer, accessing the string length, retrieving the string,
or getting the binary value for a prime, we will need to check that there are at least the required number
of bytes in the buffer. If there aren't, the buffer will need to be compacted, to shift what's left back to the
start, and then replenished. Since we want to do this at three different points in the code, a method for
this operation will come in handy:
private static int replenish(FileChannel channel, ByteBuffer buf)
throws IOException {
// Number of bytes left in file
long bytesLeft = channel.size() - channel.position();
if(bytesLeft == 0L) // If there are none
return -1; // we have reached the end
buf.compact().limit(buf.position()
+ (bytesLeft<buf.remaining() ? (int)bytesLeft : buf.remaining()));
return channel.read(buf);
}
This method first checks that there really are some bytes left in the file with which to replenish the
buffer. It then compacts the buffer and sets the limit for the buffer. The limit is automatically set to the
capacity, but it is possible that the number of bytes left in the file is insufficient to fill the rest of the
buffer. In this case the limit is set to accommodate the number of bytes available from the file. Note the
throws clause. This indicates that the method can throw exceptions of type IOException . Exceptions
of this type that are thrown are not handled by the code in the body of the method but are passed on to
the calling method so we will need to put calls for this method in a try block. We can put the whole
program together now.
Try It Out - Reading into a Large Buffer
Here are the changes to the original program code to read data into a large buffer:
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class ReadPrimesMixedData {
public static void main(String[] args) {
// Create the file input stream and get the file channel as before...
try {
Search WWH ::




Custom Search