1. 程式人生 > 實用技巧 >Netty的ByteBuf API(2)

Netty的ByteBuf API(2)

繼上一章 Netty之ByteBuf 之後,我們繼續來談 ByteBuf 的 API

清理操作

discardReadBytes 操作

因為 TCP 底層可能粘包,幾百個整包訊息被 TCP 粘包後作為一個整包傳送。這樣,通過 discardReadBytes 操作可以重用之前已經解碼過的緩衝區,從而防止接收緩衝區因為容量不足導致的擴張。
需要指出的是,呼叫 discardReadBytes 會發生位元組陣列的記憶體複製,所以頻繁呼叫將會導致效能下降,因此在呼叫它之前要確認你確實需要這樣做,例如犧牲效能來換取更多的可用記憶體。

如圖所示,capacity 保持不變,reaerIndex = 0,writerIndex -= readerIndex,紅色部分的資料發生拷貝。

clear 操作

clear 操作主要用來操作位置指標,並不會清空緩衝區內容本身。

mark 操作

mark 操作針對之前的操作進行回滾

  • markReaderIndex() : markedReaderIndex = readerIndex
  • resetReaderIndex() : readerIndex = markedReaderIndex
  • markWriterIndex() : markedWriterIndex = writerIndex
  • resetWriterIndex() : writerIndex = markedReaderIndex

查詢操作

查詢操作的返回值特點:找到了符合條件的,返回索引,否則返回-1
查詢操作的引數特點 :可以指定起始座標和查詢長度,但是起始座標+查詢長度不能超過可讀位元組數。

  • 第一類:從當前 ByteBuf 定位中首次出現 value 的位置
indexOf(fromIndex:int, toIndex:int, value:byte) // 起始索引 fromIndex,終點 toIndex
bytesBefore(value:byte)                         // 起始索引 readerIndex,終點 writerIndex
bytesBefore(length:int, value:byte)             // 起始索引 readerIndex,終點 readerIndex+length <= writerIndex
bytesBefore(index:int, length:int, value:byte)  // 起始索引 index,終點 index+length <= writerIndex
  • 第二類:指明一個函式引數 ByteBufProcessor
forEachByte(processor:ByteBufProcessor)                        // 起始索引 readerIndex,終點 writerIndex
forEachByte(index:int, length:int, processor:ByteBufProcessor) // 起始索引 index,終點 index+length
forEachByteDesc(processor:ByteBufProcessor)                    // 起始索引 writerIndex-1,直到 readerIndex
forEachByteDesc(index:int, length:int, processor:ByteBufProcessor) // 起始索引 index,直到 index+length

ByteBufProcessor

  • 可以查詢非某位元組 以 FIND_NOT_ 為字首
  • 尋找空位元組 FIND_NUL : NUL (0x00)
  • 尋找回車 FIND_CR : CR ('\r')
  • 尋找換行符 FIND_LF : LF ('\n')
  • 尋找回車或者換行符 FIND_CRLF : CR ('\r') or LF ('\n')
  • 尋找空格 FIND_ASCII_SPACE : (' ')
  • 尋找行內空白 FIND_LINEAR_WHITESPACE : (' ') or ('\t')
  • 尋找分號 FIND_SEMI_COLON : (';')
  • 尋找逗號 FIND_COMMA : (',')

Derived buffers

類似於資料庫的檢視,ByteBuf 提供了多個介面用於建立某個 ByteBuf 的檢視或者複製 ByteBuf,具體方法如下:

建立共享緩衝區的檢視

duplicate():ByteBuf

  • 共享緩衝區:複製後的緩衝區與操作的 ByteBuf 共享緩衝區內容
  • 獨立索引:複製後的新 ByteBuf 物件維護自己獨立的讀寫索引,複製操作本身不修改原 ByteBuf 讀寫索引。

建立獨立的副本

copy():ByteBuf
copy(int index, int length):ByteBuf

  • 獨立緩衝區:複製後的緩衝區,獨立於操作的 ByteBuf 緩衝區,包含操作的 ByteBuf 中的全部或者區域性的內容
  • 獨立索引:新 ByteBuf 物件的讀寫索引與之前的獨立

建立子緩衝區

建立緩衝區可讀位元組的切片
slice():ByteBuf // 起始位置從 readerIndex 到 writerIndex
slice(int index, int length) // 起始位置從 index 到 index + length

  • 共享緩衝區:返回後的 ByteBuf 與 原 ByteBuf 內容共享
  • 獨立索引:讀寫索引獨立維護。初始化時,readerIndex=0,writerIndex 等於可讀位元組數,或者等於引數 length

轉換成標準 ByteBuffer

nioBuffer():ByteBuffer
nioBuffer(int index, int length):ByteBuffer
兩者共享同一個緩衝區內容引用。對 ByteBuffer 的讀寫操作不會改變 ByteBuf 的讀寫索引。
需要注意的是,返回後的 ByteBuffer 無法感知原 ByteBuf 的動態拓展操作。