Java Reference
In-Depth Information
Reading Binary Data
When you read binary data, you still read bytes from the file, so the process is essentially the same as you
used in the previous example. You just use a different type of view buffer to access the data. To read the
primes.bin file, you have some options for the size of the byte buffer. The number of bytes in the buffer
should be a multiple of eight because a prime value is of type long , so as long as it's a multiple of eight,
you can make it whatever size you like. You could allocate a buffer to accommodate the number of primes
that you want to output to the command line — six values, say. This would make accessing the data very
easy because you need to set up a view buffer of type LongBuffer only each time you read from the file.
One thing against this is that reading such a small amount of data from the file in each read operation might
not be a very efficient way to read the file. However, in the interests of understanding the mechanics of this,
let's see how it would work anyway. The buffer would be created like this:
final int PRIMECOUNT = 6; // Number of primes to read at a time
final int LONG_BYTES = 8; // Number of bytes for type long
ByteBuffer buf = ByteBuffer.allocate(LONG_BYTES*PRIMECOUNT);
You can then read the primes in a while loop inside the try block that creates the channel using a view
buffer of type LongBuffer . Calling the asLongBuffer() method for the ByteBuffer object, buf , creates
the view buffer. The LongBuffer class offers you a choice of four get() methods for accessing values of
type long in the buffer:
get() extracts a single value of type long from the buffer at the current position and returns it.
The buffer position is then incremented by one.
get(int index) extracts a single value of type long from the buffer position specified by the
argument and returns it. The current buffer position is not altered. Remember: The buffer position
is in terms of values.
get(long[] values) extracts values.length values of type long from the buffer starting at
the current position and stores them in the array values . The current position is incremented by
the number of values retrieved from the buffer. The method returns a reference to the buffer as
type LongBuffer . If insufficient values are available from the buffer to fill the array that you pass
as the argument — in other words, limit-position is less than values.length — the method
throws an exception of type BufferUnderflowException, no values are transferred to the array,
and the buffer's position is unchanged.
get(long[] values, int offset, int length) extracts length values of type long from
the buffer starting at the current position and stores them in the values array, starting at val-
ues[offset] . The current position is incremented by the number of values retrieved from the
buffer. The method returns a reference to the buffer as type LongBuffer . If there are insufficient
values available from the buffer the method behaves in the same way as the previous version.
The BufferUnderflowException class is a subclass of RuntimeException , so you are not obliged to
catch this exception.
You could access the primes in the buffer like this:
LongBuffer longBuf = ((ByteBuffer)(buf.flip())).asLongBuffer();
System.out.println(); // Newline for the buffer contents
while(longBuf.hasRemaining()) { // While there are values
System.out.print(" " + longBuf.get()); // output them on the same line
}
Search WWH ::




Custom Search