/**
* ByteBuf是一個連續隨機訪問的bytes序列,是原始byte數組及ByteBuffer的頂層抽象。
*
* buffer建立:
* 推薦使用工具類Unpooled中的方法進行建立,也能夠調用實現類的構造方法建立。
*
* 隨機訪問索引:
* 和一般的原始byte數組同樣,ByteBuf使用基於0的索引,即第一個字節的索引爲0,最後一個字節的索引爲 capacity - 1,
*
* ByteBuf buffer = ...;
* for (int i = 0; i < buffer.capacity(); i ++) {
* byte b = buffer.getByte(i);
* System.out.println((char) b);
* }
*
* 連續訪問索引:
* ByteBuf提供兩個指針變量readerIndex、writerIndex分別用於讀寫操做,以下圖表,兩個變量將
* ByteBuf分割爲三部分。
*
* +-------------------+------------------+------------------+
* | discardable bytes | readable bytes | writable bytes |
* | | (CONTENT) | |
* +-------------------+------------------+------------------+
* | | | |
* 0 <= readerIndex <= writerIndex <= capacity
*
* 可讀取的字節(實際存儲的內容):
* 這一部分是數據實際存儲的位置,read和skip方法就是在這塊數據上執行獲取和跳過操做,同時read操
* 做會增長可讀取字節數。若是read操做的參數是一個ByteBuf,而且未指定存儲位置,則參數ByteBuf
* 的writeIndex 也會隨着增加。
*
* 可讀取的數據不足會拋出IndexOutOfBoundsException異常,新分配內存,包裝或複製的buffer的
* readerIndex爲0.
*
* 遍歷buffer;
*
* ByteBuf buffer = ...;
* while (buffer.isReadable()) {
* System.out.println(buffer.readByte());
* }
*
* 可寫入字節: *
* 這一部分是須要填充的未定義空間,write方法會從當前writeIndex位置寫入數據並增長writeIndex值,
* 若是參數是ByteBuf且並未指定源索引,則參數ByteBuf的readerIndex也會隨着增加。
*
* 若是當前可寫空間不足,則拋出IndexOutOfBoundsException異常,新分配內存,包裝或複製的buffer
* 的writerIndex爲buffe的capacity容量。
* 隨機填充
* ByteBuf buffer = ...;
* while (buffer.maxWritableBytes() >= 4) {
* buffer.writeInt(random.nextInt());
* }
*
* 可廢棄字節:
* 這一部分爲已經執行過讀取操做的數據,初始空間爲0,隨着read操做的執行,最大增加至writeIndex值。
* 可廢棄字節能夠經過調用discardReadBytes()來丟棄,並從新標識爲未使用。以下所示:
* discardReadBytes()執行以前:
*
* +-------------------+------------------+------------------+
* | discardable bytes | readable bytes | writable bytes |
* +-------------------+------------------+------------------+
* | | | |
* 0 <= readerIndex <= writerIndex <= capacity
*
*
* discardReadBytes()執行以後:
*
* +------------------+--------------------------------------+
* | readable bytes | writable bytes (got more space) |
* +------------------+--------------------------------------+
* | | |
* readerIndex (0) <= writerIndex (decreased) <= capacity
*
* 須要注意的是,一般狀況下,discardReadBytes()操做沒法保證buffer的可寫數據。根據同的buffer
* 實現,大多數狀況下,可寫數據空間不會被移動,甚至會被徹底不一樣的數據填充。
*
* 清除索引:
* clear()方法能夠將buffer的readerIndex和writeIndex都置爲0,可是並不清除buffer的數據,
* 另外須要注意是區分和ByteBuffer#clear()方法的不一樣。
* <h4>Clearing the buffer indexes</h4>
*
* <pre>
* clear()執行以前:
*
* +-------------------+------------------+------------------+
* | discardable bytes | readable bytes | writable bytes |
* +-------------------+------------------+------------------+
* | | | |
* 0 <= readerIndex <= writerIndex <= capacity
*
*
* clear()執行以後:
*
* +---------------------------------------------------------+
* | writable bytes (got more space) |
* +---------------------------------------------------------+
* | |
* 0 = readerIndex = writerIndex <= capacity
*
* 查詢操做:
* 單字節查詢可使用 indexOf(int, int, byte) 方法,bytesBefore(int, int, byte)
* 方法對於處理null結尾的字符串會特別有用。
* 複雜查詢可使用 forEachByte(int, int, ByteProcessor) 方法(ByteProcessor 提供遍歷字節集合機制, 方法中使用ByteProcessor的特定實現類)
*
* 標記和重置:
* ByteBuf中存在兩種標記變量,分別用於存儲readerIndex和writerIndex,能夠經過調用reset()
* 方法來重置任意其一。除了沒有readlimit變量,ByteBuf和InputStream具備相同的標記和和重置操做機制,
*
* 衍生buffer:
* 經過調用ByteBuf的如下方法能夠建立一個已知buffer的鏡像視圖。
*
* #duplicate()
* #slice()
* #slice(int, int)
* #readSlice(int)
* #retainedDuplicate()
* #retainedSlice()
* #retainedSlice(int, int)
* #readRetainedSlice(int)
*
* buffer視圖雖然和源buffer共享同一起內存,可是擁有徹底獨立的readerIndex,writeIndex和標記索引。
* 這和NIO buffer機制很是類似。
*
* 若是要獲取一份全新的buffer備份,能夠執行buffer的copy()方法。
*
* <h4>Non-retained and retained derived buffers</h4>
*
* duplicate()、slice(int, int)、readSlice(int)並未在新生成的衍生buffer執行retain()操做,所以
* 衍生buffer的引用計數沒有增加。retainedDuplicate()、retainedSlice()、readRetainedSlice()
* 方法能夠生成一個包含引用計數增加而且產生較少垃圾()的衍生buffer。
*
* JDK byte array轉換
*
* Byte array
*
* 由byte數組(byte[])包裝生成的ByteBuf,能夠直接經過數據中的方法進行操做。
* 判斷方法:hasArray()。
*
* NIO Buffers
* 若是一個ByteBuf能夠被轉換爲NIO ByteBuffer,那麼就能夠經過nioBuffer的方法來操做ByteBuf。
* 判斷方法:nioBufferCount()。
*
* 字符串輸出:
* ByteBuf存在多種toString()方法,須要注意的是toString()方法並非一個轉換方法。
*
* I/O Streams
*
* 詳見 緩衝輸入輸出流 ByteBufInputStream ByteBufOutputStream.
*/