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 的动态拓展操作。

posted @   极客子羽  阅读(215)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示