官方文檔:
Class ByteBuf ------------------ Netty API Reference (4.0.54.Final)
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 (byte[]) and NIO buffers.
任意連續(xù)可用的序列,包含0或0個以上字節(jié)砰盐。此接口提供多個原始字節(jié)數(shù)組和NIO緩沖區(qū)的抽象視圖。
Creation of a buffer
It is recommended to create a new buffer using the helper methods in Unpooled rather than calling an individual implementation's constructor.
強烈建議用幫助類Unpooled的方法來創(chuàng)建緩沖區(qū),而非直接調用自己的構造函數(shù)。
Random Access Indexing
Just like an ordinary primitive byte array, ByteBuf 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:
就像普通的原始字節(jié)數(shù)組,ByteBuf以0索引開始熊泵。這意味著第一個字節(jié)的索引總是0,而最后一個字節(jié)的索引總是(ByteBuf.capacity-1)甸昏。例如顽分,你要遍歷一個字符緩沖區(qū),你可以用下面這種方法施蜜,不論它的內部實現(xiàn)如何卒蘸。
ByteBuf buffer = ...;
for (int i = 0; i < buffer.capacity(); i ++) {
byte b = buffer.getByte(i);
System.out.println((char) b);
}
Sequential Access Indexing
ByteBuf 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:
ByteBuf 提供兩個指針變量來實現(xiàn)連續(xù)讀和寫操作 - readerIndex用于讀操作,writerIndex用于寫操作翻默。下圖顯示了緩沖區(qū)被兩個指針分成三個部分缸沃。
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 ByteBuf and no destination index is specified, the specified buffer's writerIndex 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.
可讀字符(實際內容)
這里是實際數(shù)據(jù)的存儲位置恰起。任何以"read"和"skip"開頭的操作會以當前的readerIndex上開始讀取或忽略指定數(shù)據(jù),讀取完畢后readerIndex增加趾牧。如果讀操作的參數(shù)也是ByteBuf村缸,且沒有指定目標索引,那么緩沖區(qū)的writerIndex也會隨之增加武氓。
如果沒有足夠的內容可讀梯皿,會拋出IndexOutOfBoundsException。新分配的县恕、被封裝的或拷貝的緩沖區(qū)的readerIndex默認值為0东羹。
// Iterates the readable bytes of a buffer.
ByteBuf buffer = ...;
while (buffer.isReadable()) {
System.out.println(buffer.readByte());
}
Writable bytes
This segment is a undefined space which needs to be filled. Any operation whose name starts 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 ByteBuf, 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.
可寫字符
這里是要被填充的被定義空間。任何以"write"開頭的操作會以當前writerIndex開始寫數(shù)據(jù)忠烛,寫完后writerIndex增加属提。如果寫操作的參數(shù)也為ByteBuf,且沒有指定源索引美尸,那么緩沖區(qū)的readerIndex也會隨之增加冤议。
如果沒有足夠的可寫字節(jié),會拋出IndexOutOfBoundsException师坎。新分配的緩沖區(qū)的writerIndex默認值為0恕酸。封裝或拷貝的緩沖區(qū)的writerIndex默認值為緩沖區(qū)的capacity。
// Fills the writable bytes of a buffer with random integers.
ByteBuf buffer = ...;
while (buffer.maxWritableBytes() >= 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:
可廢棄字節(jié)
這部分包含已讀字節(jié)胯陋。初始化時蕊温,這部分的大小為0,但隨著讀操作的執(zhí)行遏乔,大小會達到writerIndex义矛。已讀字節(jié)可以通過調用discardReadBytes()廢棄,回收可用的空間盟萨。下圖描述了這個過程
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.
請注意調用discardReadBytes()后不能保證可讀字節(jié)的內容凉翻。可讀字節(jié)在大多數(shù)情況下不會被移除捻激,還可能會根據(jù)不同的底層的緩沖區(qū)實現(xiàn)填充不同的數(shù)據(jù)制轰。
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 Buffer.clear().
你可以調用clear()把readerIndex和writerIndex設置為0。它不會清空緩沖區(qū)的內容铺罢,而僅僅是清除2個指針艇挨。請注意這個操作和Buffer.clear()在語義上的不同。
Search operations
For simple single-byte searches, use indexOf(int, int, byte) and bytesBefore(int, int, byte). bytesBefore(byte) is especially useful when you deal with a NUL-terminated string. For complicated searches, use forEachByte(int, int, ByteBufProcessor) with a ByteBufProcessor implementation.
對于簡單的單字節(jié)搜索韭赘,使用indexof(int, int, byte)和bytesBefore(int, int, byte)缩滨。bytesBefore(byte)在處理以NUL結尾的字符串時特別有效。對于復雜字符的搜索,使用forEachByte(int, int, ByteBufProcessor)
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.
每個緩沖區(qū)有兩個標記索引脉漏,一個存儲readerIndex苞冯,另一個存儲writerIndex。你總是可以調用reset方法來復位其中一個索引侧巨。標記和重置方法在輸入流中以相同的方式處理舅锄,只不過沒有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.
Also be aware that obtaining derived buffers will NOT call retain() and so the reference count will NOT be increased.
你可以通過調用duplicate()司忱、slice()皇忿、或者slice(int, int),創(chuàng)建一個已有緩沖區(qū)的視圖坦仍。衍生的緩沖區(qū)有獨立的readerIndex鳍烁,writerIndex,和標記索引繁扎,然而它們共享內部數(shù)據(jù)幔荒,就像NIO buffer。
防止全新地復制一個已存在的緩沖區(qū)梳玫,請用copy()替代爹梁。
還有,得到一個衍生的緩沖區(qū)不會調用retain()提澎,所以引用計數(shù)不會增加姚垃。
Conversion to existing JDK types
Byte array
If a ByteBuf is backed by a byte array (i.e. byte[]), you can access it directly via the array() method. To determine if a buffer is backed by a byte array, hasArray() should be used.
NIO Buffers
If a ByteBuf can be converted into an NIO ByteBuffer which shares its content (i.e. view buffer), you can get it via the nioBuffer() method. To determine if a buffer can be converted into an NIO buffer, use nioBufferCount().
Strings
Various toString(Charset) methods convert a ByteBuf into a String. Please note that toString() is not a conversion method.
I/O Streams
Please refer to ByteBufInputStream and ByteBufOutputStream.
字節(jié)數(shù)組
如果ByteBuf是字節(jié)數(shù)組,可以用array()方法直接轉換虱朵。判斷ByteBuf是否可以轉化為字節(jié)數(shù)組莉炉,可以用hasArray()來確認。
NIO緩沖區(qū)
如果一個ByteBuf可以轉化為包含一樣數(shù)據(jù)的NIO ByteBuffer碴犬,可以使用nioBuffer()來轉化。判斷ByteBuf是否可以轉化為NIO buffer梆暮,可以用nioBufferCount()來確認服协。
字符串
多種 toString(Charset)方法可將ByteBuf轉化為String。注意toString()不是轉化方法啦粹。
I/O流
參考ByteBufInputStream和ByteBufOutputStream