Java Reference
In-Depth Information
...
467 479 487 491 499 503Exception in thread "main" java.nio.BufferUnderflo
wException
at java.nio.LongBuffer.get(LongBuffer.java:609)
at java.nio.LongBuffer.get(LongBuffer.java:633)
at ReadPrimes.main(ReadPrimes.java:28)
How It Works
The reason is doesn't work very well is that the number of primes in the file is not divisible by the
number of primes that we read into the view buffer. This is determined by the number of elements in
the array primes . On the last iteration of the while loop that reads the file, there are insufficient
values to fill the array so the get() method throws an exception of type
BufferUnderflowException .
One way to deal with this is to catch the exception that is thrown. It's not a particularly good way
because of the overhead in throwing and catching exceptions, but let's see how we could do it anyway.
We could rewrite the while loop like this:
int primesRead = 0;
while(inChannel.read(buf) != -1) {
try {
((ByteBuffer)(buf.flip())).asLongBuffer().get(primes);
primesRead = primes.length;
} catch(BufferUnderflowException e) {
LongBuffer longBuf = buf.asLongBuffer();
primesRead = longBuf.remaining();
longBuf.get(primes,0, primesRead);
}
System.out.println();
for(int i = 0 ; i< primesRead ; i++)
System.out.print(" "+primes[i]);
buf.clear(); // Clear the buffer for the next read
}
When the exception is thrown on the last iteration, we catch it and read the remaining values in the
view buffer using the alternate form of the get() method, where the second argument specifies the first
array element to store a value in and the third argument specifies the number to be stored. To take
account of the possibility that less than the whole array will contain primes when we output it, we set
the number of primes that are read in the loop. Note that we must set the value of primesRead inside
the catch block before we execute the get() method. Afterwards the number remaining will be zero.
Of course, although this works, it is a very poor way to deal with the problem. A better way is to avoid
it altogether, like this:
int primesRead = 0;
while(inChannel.read(buf) != -1) {
Search WWH ::




Custom Search