Java Reference
In-Depth Information
buf.limit(2*charBuf.length()); // Set byte buffer limit
Because each Unicode character occupies 2 bytes, the statement sets the byte buffer limit to twice the
number of characters in charBuf .
With the byte buffer set up ready to be written to the channel, you write the data to the file with the state-
ment:
channel.write(buf); // Write buffer to the
channel
You now need to reset the limit and position for both the byte buffer and the view buffer to be ready for
the next proverb to be written. The following two statements do this:
buf.clear();
charBuf.clear();
Calling the clear() method for a buffer sets the buffer's position back to 0 and its limit to the capacity.
This example looks a little more complicated than it really is because of all the statements tracing the
states of the buffer. If you delete these, you find the code is quite short.
The output shown for this example was produced on a Microsoft Windows system where a newline is
written as two characters, CR and LF. If you are using Linux or other operating systems that represent a
newline as a single NL character, the values for position after the buffer has been loaded by the For-
matter object are less.
Direct and Indirect Buffers
When you allocate a byte buffer by calling the static allocate() method for the ByteBuffer class, you get
an indirect buffer . An indirect buffer is not used by the native I/O operations, which have their own buffers.
Data to be written to a file has to be copied from your indirect buffer to the buffer that the native output
routine uses before the write operation can take place. Similarly, after a read operation the data is copied
from the input buffer used by your operating system to the indirect buffer that you allocate.
Of course, with small buffers and limited amounts of data being read, using an indirect buffer doesn't add
much overhead. With large buffers and lots of data, it can make a significant difference, though. In this case,
you can use the allocateDirect() method in the ByteBuffer class to allocate a direct buffer . The JVM
tries to make sure that the native I/O operation makes use of the direct buffer, thus avoiding the overhead of
the data copying process. The allocation and de-allocation of a direct buffer carries its own overhead, which
might outweigh any advantages gained if the buffer size and data volumes are small.
You can test whether a buffer object encapsulates a direct buffer by calling its isDirect() method. This
returns true if it is a direct buffer and false otherwise.
You could try this out by making a small change to the WriteProverbs example. Just replace the state-
ment
ByteBuffer buf = ByteBuffer.allocate(2*maxLength + 4);
with the following two statements:
Search WWH ::




Custom Search