ChannelBufferの紹介
12582 ワード
A random and sequential accessible sequence of zero or more bytes (octets). This interface provides an abstract view for one or more primitive byte arrays (
It is recommended to create a new buffer using the helper methods in
Just like an ordinary primitive byte array,
This segment is where the actual data is stored. Any operation whose name starts with
If there's not enough content left,
This segment is a undefined space which needs to be filled. Any operation whose name ends with
If there's not enough writable bytes left,
This segment contains the bytes which were read already by a read operation. Initially, the size of this segment is
Please note that there is no guarantee about the content of writable bytes after calling
You can set both readerIndex and writerIndex to 0 by calling clear() . It does not clear the buffer content (e.g. filling with
Various
There are two marker indexes in every buffer. One is for storing
You can create a view of an existing buffer by calling either
In case a completely fresh copy of an existing buffer is required, please call
Various
Various
Please refer to
byte[]
) and NIO buffers . Creation of a buffer
It is recommended to create a new buffer using the helper methods in
ChannelBuffers
rather than calling an individual implementation's constructor. Random Access Indexing
Just like an ordinary primitive byte array,
ChannelBuffer
uses zero-based indexing . It means the index of the first byte is always 0
and the index of the last byte is always capacity - 1
. For example, to iterate all bytes of a buffer, you can do the following, regardless of its internal implementation: ChannelBuffer buffer = ...;
for (int i = 0; i < buffer.capacity(); i ++) {
byte b = array.getByte(i);
System.out.println((char) b);
}
Sequential Access Indexing
ChannelBuffer
provides two pointer variables to support sequential read and write operations - readerIndex
for a read operation and writerIndex
for a write operation respectively. The following diagram shows how a buffer is segmented into three areas by the two pointers: +-------------------+------------------+------------------+
| discardable bytes | readable bytes | writable bytes |
| | (CONTENT) | |
+-------------------+------------------+------------------+
| | | |
0 <= readerIndex <= writerIndex <= capacity
Readable bytes (the actual content)
This segment is where the actual data is stored. Any operation whose name starts with
read
or skip
will get or skip the data at the current readerIndex
and increase it by the number of read bytes. If the argument of the read operation is also a ChannelBuffer
and no destination index is specified, the specified buffer's readerIndex
is increased together. If there's not enough content left,
IndexOutOfBoundsException
is raised. The default value of newly allocated, wrapped or copied buffer's readerIndex
is 0
. // Iterates the readable bytes of a buffer.
ChannelBuffer buffer = ...;
while (buffer.readable()) {
System.out.println(buffer.readByte());
}
Writable bytes
This segment is a undefined space which needs to be filled. Any operation whose name ends with
write
will write the data at the current writerIndex
and increase it by the number of written bytes. If the argument of the write operation is also a ChannelBuffer
, and no source index is specified, the specified buffer's readerIndex
is increased together. If there's not enough writable bytes left,
IndexOutOfBoundsException
is raised. The default value of newly allocated buffer's writerIndex
is 0
. The default value of wrapped or copied buffer's writerIndex
is the capacity
of the buffer. // Fills the writable bytes of a buffer with random integers.
ChannelBuffer buffer = ...;
while (buffer.writableBytes() >= 4) {
buffer.writeInt(random.nextInt());
}
Discardable bytes
This segment contains the bytes which were read already by a read operation. Initially, the size of this segment is
0
, but its size increases up to the writerIndex
as read operations are executed. The read bytes can be discarded by calling discardReadBytes()
to reclaim unused area as depicted by the following diagram: BEFORE discardReadBytes()
+-------------------+------------------+------------------+
| discardable bytes | readable bytes | writable bytes |
+-------------------+------------------+------------------+
| | | |
0 <= readerIndex <= writerIndex <= capacity
AFTER discardReadBytes()
+------------------+--------------------------------------+
| readable bytes | writable bytes (got more space) |
+------------------+--------------------------------------+
| | |
readerIndex (0) <= writerIndex (decreased) <= capacity
Please note that there is no guarantee about the content of writable bytes after calling
discardReadBytes()
. The writable bytes will not be moved in most cases and could even be filled with completely different data depending on the underlying buffer implementation. Clearing the buffer indexes
You can set both readerIndex and writerIndex to 0 by calling clear() . It does not clear the buffer content (e.g. filling with
0
) but just clears the two pointers. Please also note that the semantic of this operation is different from ByteBuffer.clear()
. BEFORE clear()
+-------------------+------------------+------------------+
| discardable bytes | readable bytes | writable bytes |
+-------------------+------------------+------------------+
| | | |
0 <= readerIndex <= writerIndex <= capacity
AFTER clear()
+---------------------------------------------------------+
| writable bytes (got more space) |
+---------------------------------------------------------+
| |
0 = readerIndex = writerIndex <= capacity
Search operations
Various
indexOf()
methods help you locate an index of a value which meets a certain criteria. Complicated dynamic sequential search can be done with ChannelBufferIndexFinder
as well as simple static single byte search. Mark and reset
There are two marker indexes in every buffer. One is for storing
readerIndex
and the other is for storing writerIndex
. You can always reposition one of the two indexes by calling a reset method. It works in a similar fashion to the mark and reset methods in InputStream
except that there's no readlimit
. Derived buffers
You can create a view of an existing buffer by calling either
duplicate()
, slice()
or slice(int, int)
. A derived buffer will have an independent readerIndex
, writerIndex
and marker indexes, while it shares other internal data representation, just like a NIO buffer does. In case a completely fresh copy of an existing buffer is required, please call
copy()
method instead. Conversion to existing JDK types
NIO Buffers
Various
toByteBuffer()
and toByteBuffers()
methods convert a ChannelBuffer
into one or more NIO buffers. These methods avoid buffer allocation and memory copy whenever possible, but there's no guarantee that memory copy will not be involved or that an explicit memory copy will be involved. Strings
Various
toString(String)
methods convert a ChannelBuffer
into a String
. Please note that toString()
is not a conversion method. I/O Streams
Please refer to
ChannelBufferInputStream
and ChannelBufferOutputStream
.