Java Reference
In-Depth Information
File written is 2671 bytes.
The length of the file is considerably less than before, because you are writing the string as bytes rather
than Unicode characters. The part of the code that is different is shown shaded and I'll concentrate on
explaining that.
How It Works
This time you want the channel variable to be stored as type
GatheringByteChannel
because that in-
terface declares the gathering write methods. To do this you must first cast the
SeekableByteChannel
reference that the
newByteChannel()
method returns to type
FileChannel
. This is necessary because
the
SeekableByteChannel
interface does not implement the
GatheringByteChannel
interface, as you
can see if you refer to
Figure 10-9
.
Of course, you could also store the reference in a variable of type
FileChannel
, which would make all the methods in the class available.
You use three byte buffers — one for the string length, one for the string itself, and one for the binary
prime value:
ByteBuffer[] buffers = new ByteBuffer[3]; // Array of buffer
references
You create a
ByteBuffer[]
array with three elements to hold references to the buffers that you need. The
buffers to hold the string length and the prime value are fixed in length so you are able to create those
straightaway to hold 8 bytes each:
buffers[0] = ByteBuffer.allocate(8); // To hold a double
value
buffers[2] = ByteBuffer.allocate(8); // To hold a long
value
Because the string length can vary, you have to create the buffer that holds the string dynamically. You
do this inside the
for
loop that iterates over all the prime values you have in the
primes
array.
After assembling the prime string as
primeStr
, you transfer the length of this string to the first buffer in
the array:
buffers[0].putDouble((double) primeStr.length()).flip();
Note that you are able to flip the buffer in the same statement after the data value has been transferred,
so it is set up ready to be written to the file. This uses the buffer reference that the
putDouble(
) method
returns to call
flip()
.
Next, you create the buffer to accommodate the string, load the byte array equivalent of the string, and
flip the buffer:
buffers[1] = ByteBuffer.allocate(primeStr.length());
buffers[1].put(primeStr.getBytes()).flip();
All of the
put()
methods for the byte buffers you are using in this example automatically update the
buffer position, so you can flip each buffer as soon as the data is loaded. As an alternative to allocating
this byte buffer directly to accommodate the byte array from the string, you could call the static
wrap()
method in the
ByteBuffer
class that wraps a byte array. You could achieve the same as the previous two
statements with the following single statement: