• 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 (' ')
    • 寻找换行符 FIND_LF : LF (' ')
    • 寻找回车或者换行符 FIND_CRLF : CR (' ') or LF (' ')
    • 寻找空格 FIND_ASCII_SPACE : (' ')
    • 寻找行内空白 FIND_LINEAR_WHITESPACE : (' ') or (' ')
    • 寻找分号 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 的动态拓展操作。

  • 相关阅读:
    小刘的PHP面试碰到的坑
    小刘的PHP面试碰到的坑
    小刘的项目经验
    04 mysql 深入浅出索引(上)
    CGI,FastCGI和PHP-FPM之间的关系和区别。
    mysql客户端模拟脏读、幻读和可重复读
    mysql 3 | 事务隔离:为什么你改了我还看不见?
    sa账号无法登陆sqlserver2008
    Java单体应用
    Java单体应用
  • 原文地址:https://www.cnblogs.com/kendoziyu/p/io-netty-buffer_2.html
Copyright © 2020-2023  润新知