博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Netty Associated -- ByteBuf
阅读量:6814 次
发布时间:2019-06-26

本文共 2726 字,大约阅读时间需要 9 分钟。

ByteBuf

ByteBuf是Netty的Server与Client之间通信的数据传输载体.他提供了一个byte数组(byte[])的抽象视图

buffer创建

我们推荐通过一个Unpooled的帮助方法来创建新的buffer而不是通过调用独立的构造器来创建

随机访问索引

就像普通的原声字节数组一样, ByteBuf使用零基坐标(zero-based indexing). 这表示第一个字节的坐标总是0, 最后一个字节的坐标总是capacity - 1.例如, 要遍历buffer的所有字节,你可以按下面这样做:

ByteBuf buffer = ...;   for (int i = 0; i < buffer.capacity(); i ++) {       byte b = buffer.getByte(i);       System.out.println((char) b);   }

连续访问索引

ByteBuf提供了两个指针变量来支持顺序读写操作 - readerIndex用来支持读操作, writerIndex用来支持写操作.下面的表格显示了一个buffer是如何通过两个指针分段为三部分的

可读字节(真实内容)

这个段是真实数据储存的地方.任何名字以start或skip开始的操作都会增加当前readerIndex他读过的字节数.如果读操作的参数也是一个ByteBuf, 并且没有指定目的地坐标, 那么指定ByteBuf的writerIndex也会一起增加

如果buf没有足够的内容可供读取,会抛出IndexOutOfBoundsException. 最新分配的buffer, buffer的包装类和副本的readerIndex默认值都是0

// Iterates the readable bytes of a buffer.   ByteBuf buffer = ...;   while (buffer.readable()) {       System.out.println(buffer.readByte());   }

可写字节

这个段是一个等待被填满的未定义空间.任何名字已write结尾的操作都会在当前writerIndex上写入数据,并且将writerIndex的值增加写入的数据数.如果写入操作的参数也是一个ByteBuf, 并且没有元坐标被指定, 那么指定的buffer的readerIndex也会一起增加

如果没有组合够的空间剩余来写,会抛出IndexOutOfBoundsException. 最新分配的buffer的writerIndex的默认值是0, 包装类和buffer副本的writerIndex是buffer的容量

// Fills the writable bytes of a buffer with random integers.   ByteBuf buffer = ...;   while (buffer.maxWritableBytes() >= 4) {       buffer.writeInt(random.nextInt());   }

 丢弃字节

这个段包含已经被读操作读过的字节.初始化的时候, 这个段的大小为0,这个段的大小会随着读操作一直增加到writerIndex.读字节可以通过discardReadBytes()回收未被使用的区域将其变为丢弃字节, 如下图所示

 

调用discardReadBytes()前:

 

使用discardReadBytes()后:

请注意并不能保证在调用discardReadBytes()后并不能保证可写字节的内容.可写字节在大部分情况下不会移动, 并且可能被完全不同的数据填满, 这取决于底层的buffer实现.

 

清除buffer索引

你可以通过调用clear()将readerIndex和writerIndex都设为0.这不会清除buffer内容(例如用0填充), 他仅仅是清除了两个指针.请注意这个操作的语义和ByteBuffer.clear()是不一样的

clear()前

clear()后

 

搜索操作

使用indexOf(int, int, byte)和bytesBefore(int, int, byte)可以进行最简单的单字节搜索.bytesBefore(byte)在你处理一个NUL-terminated字符串的时候特别有用.更复杂的搜索, 请使用forEachByte(int, int, ByteBufProcessor)和一个ByteBufProcessor的实现

 

标记和重置

每个buffer都有两个标记索引.一个用来保存readerIndex,另一个用来保存writerIndex.你可以通过调用reset()放来来重置他们中的一个.他的工作方式和InputStream中的mark和reset方法很像, 只是没有readlimit

 

派生buffer

你可以通过调用duplicate(), slice()或者slice(int, int)来创建一个已存在的buffer的视图.一个派生的buffer会有单独的readerIndex,writerIndex和标记坐标, 但是他共享其他数据.就像一个NIO的buffer一样.

加入你需要一个全新的buffer的copy,请调用copy()方法

 

转化为已存在的JDK类型

Byte array

假如一个ByteBuf是有一个byte数组作为支持的, 你可以直接通过array()方法访问它. 判断一个buffer是否是被byte array作为支持,调用hasArray()

只有堆内内存的ByteBuf是有array支持的, 如果是堆外内存的ByteBuf, 是不能通过array()获取到数据的, 而CompositeByteBuf可能由堆内的ByteBuf和堆外的DirectByteBuf组成, 他也不能直接通过array()获取数据

 

NIO Buffers

如果一个ByteBuf可以被转换为NIO ByteBuffer, 他共享他的内容,你可以通过nioBuffer()获取它.判断一个buffer能否被转化为NIO buffer, 使用nioBufferCount().

 

Strings

各种各样的toString(Charset)方法将一个ByteBuf转化为一个String.请注意toString()并不是一个转换方法.

 

I/O Streams

请看ByteBufInputStream和ByteBufOutputStream

转载地址:http://ecbzl.baihongyu.com/

你可能感兴趣的文章
Jabber Software:Jabber-NET、agsXMPP与Wilefire[转]
查看>>
java中判断字符串是否为数字的方法的几种方法 (转载)
查看>>
iperf测试工具
查看>>
Java 并发编程基础导航
查看>>
Docker(一):Docker入门教程
查看>>
在8086中,[ idata],[bx]表示内存单元时。可能是一个字节,也可能是一个字。
查看>>
【MPI】并行奇偶交换排序
查看>>
并发编程之线程
查看>>
python开发部署时新增数据库中表的方法
查看>>
参加2018之江杯全球人工智能大赛 :视频识别&问答(四)
查看>>
阿里云跨地域访问私网
查看>>
通过angularJS官方案例快速入门
查看>>
Introduction of OpenCascade Foundation Classes
查看>>
Surface Normal Vector in OpenCascade
查看>>
Educational Codeforces Round 38 (Rated for Div. 2)
查看>>
内部类初识
查看>>
【python3的学习之路一】输入和输出
查看>>
在Eclipse中生成接口的JUnit测试类
查看>>
Oracle SQL常用内置系统函数总结
查看>>
[POJ] #1005# I Think I Need a Houseboat : 浮点数运算
查看>>