Netty入門(四)ByteBuf 字節級別的操作


   Netty 中使用 ByteBuf 代替 Java NIO 提供的 ByteBuffer 作為字節的容器。

一、索引

  ByteBuf 提供兩個指針變量支持讀和寫操作,讀操作使用 readerIndex,寫操作使用 writerIndex。如下圖:

  

  1.  可丟棄字節,因為它們已經被讀
  2.  可讀字節,已寫入但還沒有被讀取
  3.  可寫字節

 

 二、索引管理

  1.   調用 markReaderIndex(), markWriterIndex(), resetReaderIndex() 和 resetWriterIndex() 來設置和重新定位 readerIndex 和 writerIndex,
  2.  調用 readerIndex(int) 或 writerIndex(int) 將指針移動到指定的位置
  3.  調用 clear() 同時設置 readerIndex 和 writerIndex 為 0

 

 三、查詢操作

   可以使用以 ByteBufProcessor 為參數的方法,下面例子實現了尋找一個回車符( \r ):

1 ByteBuf in = (ByteBuf)msg;
2 int index = in.forEachByte(ByteProcessor.FIND_CR);

 

 四、衍生的緩沖區

   slice 方法和 copy 方法都能實現拷貝功能,但是它們有不同之處,下面兩個例子說明了它們的不同之處。

  先看看 slice 的例子:

1 Charset utf8 = Charset.forName("UTF-8");
2 ByteBuf buf = Unpooled.copiedBuffer("Netty in Action rocks!", utf8);
3 
4 ByteBuf sliced = buf.slice(0, 14);  // 創建從0開始到14的新slice
5 System.out.println(sliced.toString(utf8));  //打印 Netty in Action
6 
7 buf.setByte(0, (byte) 'J');                 //更新索引為0的字節
8 // 斷言成功,說明slice之后兩段數據共享
9 assert buf.getByte(0) == sliced.getByte(0);

 

   這個說明 slice 返回的是原緩沖區的一個副本,共享同一片數據。因此若需要操作某段數據,使用 slice 方法。

  下面來看看 copy 方法是如何不同的:

1 Charset utf8 = Charset.forName("UTF-8");
2 ByteBuf buf = Unpooled.copiedBuffer("Netty in Action rocks!", utf8); 
3 
4 ByteBuf copy = buf.copy(0, 14);     // 注意這里使用了copy
5 System.out.println(copy.toString(utf8)); 
6 
7 buf.setByte(0, (byte) 'J');        
8 // 斷言成功,說明原數據修改對copy不影響
9 assert buf.getByte(0) != copy.getByte(0);

 

   可以看到,代碼幾乎是相同的,但所衍生的 ByteBuf 效果是不同的。

 

 五、讀 / 寫操作

  讀 / 寫操作主要有兩類:

  •  get() / set() 操作:從給定的索引開始,寫索引和讀索引保持不變
  •  read() / write() 操作:從給定的索引開始,根據字節訪問的數量,遞增當前的寫索引或讀索引。  

  需要特別注意上述兩類操作對於讀索引和寫索引的影響。

  常見的 get() 操作如下:

  

  常見的 set() 操作如下:

  

  常見的 read() 操作如下:

  

  每個 read() 方法都對應一個 write() 方法,如下:

  

 

六、更多操作  

   還有一些比較常用的方法如下:

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM