Netty中的ByteBuf

注意,此文章为Netty源码中ByteBuf的英文注释翻译,但是内容清晰易懂,如果有译文争议,参考源代码

定义

ByteBuf一个由零个或多个字节(octets)组成的随机和连续的可访问序列。这个接口为一个或多个原始字节数组(byte[])和NIO缓冲区提供一个抽象视图。 创建一个缓冲区

实例化建议以及索引

建议使用Unpooled中的辅助方法创建一个新的缓冲区,而不是调用单个实现的构造函数。 随机访问索引 就像一个普通的原始字节数组一样,ByteBuf使用基于零的索引。这意味着第一个字节的索引总是0,最后一个字节的索引总是容量-1。 例如,要遍历一个缓冲区的所有字节,你可以做以下事情,不管它的内部实现如何。

顺序访问索引 ByteBuf提供了两个指针变量来支持顺序的读和写操作--分别为读操作的readerIndex和写操作的writerIndex。下图显示了一个缓冲区是如何被这两个指针分割成三个区域的。

重要内部结构

可读字节(实际内容) 这个区段是存储实际数据的地方。任何名称以read或skip开头的操作都将获得或跳过当前readerIndex处的数据,并将其增加到读取的字节数上。如果读取操作的参数也是一个ByteBuf,并且没有指定目标索引,那么指定的缓冲区的writerIndex会被一起增加。 如果没有足够的剩余内容,会引发IndexOutOfBoundsException。新分配的、包裹的或复制的缓冲区的readerIndex的默认值是0。

可写字节 这个段是一个未定义的空间,需要被填充。任何名字以写开始的操作都会在当前的writerIndex处写入数据,并以写入的字节数增加。如果写操作的参数也是一个ByteBuf,并且没有指定源索引,那么指定缓冲区的readerIndex也会一起增加。 如果没有足够的可写字节,会引发IndexOutOfBoundsException。新分配的缓冲区的writerIndex的默认值是0,被包裹或复制的缓冲区的writerIndex的默认值是缓冲区的容量。

可丢弃的字节 这个段包含已经被读操作读过的字节。最初,这个段的大小为0,但随着读操作的执行,其大小会增加到writerIndex。通过调用discardReadBytes()可以丢弃已读的字节,以回收未使用的区域

基本操作

搜索操作

对于简单的单字节搜索,使用indexOf(int, int, byte)和bytesBefore(int, int, byte)。bytesBefore(byte)在你处理NUL结尾的字符串时特别有用。对于复杂的搜索,使用forEachByte(int, int, ByteProcessor)与ByteProcessor实现。

标记和重置

在每个缓冲区中都有两个标记索引。一个是用于存储readerIndex,另一个是用于存储writerIndex。你总是可以通过调用重置方法来重新定位这两个索引中的一个。它的工作方式与InputStream中的mark和reset方法类似,只是没有readlimit。

派生缓冲区

你可以通过调用以下方法之一来创建一个现有缓冲区的视图。 请注意,在调用discardReadBytes()后,对可写字节的内容没有任何保证。在大多数情况下,可写字节不会被移动,甚至可能被填入完全不同的数据,这取决于底层缓冲区的实现。

清除缓冲区的索引

你可以通过调用clear()将readerIndex和writerIndex都设置为0。它不会清除缓冲区的内容(例如用0填充),而只是清除这两个指针。还请注意,这个操作的语义与ByteBuffer.clear()不同。

一个派生缓冲区将有一个独立的readerIndex、writerIndex和marker索引,同时它共享其他的内部数据表示,就像一个NIO缓冲区那样。 如果需要对现有的缓冲区进行全新的复制,请调用copy()方法来代替。 非保留的和保留的派生缓冲区 注意 duplicate(), slice(), slice(int, int) 和 readSlice(int) 不会对返回的派生缓冲区调用 retain() ,因此它的引用计数不会增加。如果你需要创建一个引用次数增加的派生缓冲区,可以考虑使用 retainedDuplicate(), retainedSlice(), retainedSlice(int, int) 和 readRetainedSlice(int) ,它们可能返回一个产生较少垃圾的缓冲区实现。 转换到现有的JDK类型

关于yte数组

如果一个ByteBuf是由一个字节数组(即byte[])支持的,你可以通过array()方法直接访问它。要确定一个缓冲区是否由一个字节数组支持,应该使用hasArray()。 NIO缓冲区 如果一个ByteBuf可以转换为一个NIO ByteBuffer,共享其内容(即视图缓冲区),你可以通过nioBuffer()方法获得它。要确定一个缓冲区是否可以转换为NIO缓冲区,请使用nioBufferCount()。 字符串 各种toString(Charset)方法将ByteBuf转换为字符串。请注意,toString()不是一个转换方法。 I/O流 请参考ByteBufInputStream和ByteBufOutputStream。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值