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:
Search WWH ::




Custom Search