Netty Associated -- ByteBuf
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
Netty Associated -- ByteBuf的更多相关文章
- 【Netty】Netty之ByteBuf
一.前言 前面已经学习了Netty中传输部分,现在接着学习Netty中的ByteBuf. 二.ByteBuf 2.1 ByteBuf API 在网络上传输的数据形式为Byte,Java NIO提供了B ...
- Netty中ByteBuf的引用计数线程安全的实现原理
原文链接 Netty中ByteBuf的引用计数线程安全的实现原理 代码仓库地址 ByteBuf 实现了ReferenceCounted 接口,实现了引用计数接口,该接口的retain(int) 方法为 ...
- Netty的ByteBuf
https://blog.csdn.net/thinking_fioa/article/details/80795673 netty的ByteBuf知识点
- java.neo的ByteBuffer与Netty 的ByteBuf
JDK的ByteBuffer的缺点: 1.final byte[] hb;这是JDKde ByteBuffer对象中用于存储数据的对象声明;可以看到,其字节数组是被声明为final的,也就是长度是固定 ...
- Netty笔记--ByteBuf释放
参考资料:http://www.maljob.com/pages/newsDetail.html?id=394 参考资料:http://www.blogjava.net/liuguly/archive ...
- Netty中ByteBuf 的零拷贝
转载:https://www.jianshu.com/p/1d1fa2fe1ed9 此文章已同步发布在我的 segmentfault 专栏. 根据 Wiki 对 Zero-copy 的定义: &quo ...
- netty LEAK: ByteBuf.release() was not called before it's garbage-collected
背景.netty抛出完整的error信息如下: 2018-02-08 14:30:43.098 [nioEventLoopGroup-5-1] ERROR io.netty.util.Resource ...
- netty之ByteBuf详解
[ChannelPromise作用:可以设置success或failure 是为了通知ChannelFutureListener]Netty的数据处理API通过两个组件暴露——abstract cla ...
- Netty之ByteBuf
本文内容主要参考<<Netty In Action>>,偏笔记向. 网络编程中,字节缓冲区是一个比较基本的组件.Java NIO提供了ByteBuffer,但是使用过的都知道B ...
随机推荐
- IO知识点整理(序列化,管道流,数据流,字节数组流,与编码)
一:序列化的问题 1.序列号的使用问题 关于在序列化中的序列号的使用问题,一般要是使用. 因为,每次要序列化的类产生都会产生一个一个新的序列号,如果将这个类的程序修改后,就会产生新的序列号,以前序列化 ...
- linux系统入门一些常用命令解析
接触IT行业的时候,就使用了ubuntu系统做开发,那个时候是一头雾水,从习惯了window下的界面操作,到终端下的命令行操作,着实一开始让人很不习惯.但是没办法,那个时候公司每个人都用Ubuntu系 ...
- [转]C++ template —— 模板基础(一)
<C++ Template>对Template各个方面进行了较为深度详细的解析,故而本系列博客按书本的各章顺序编排,并只作为简单的读书笔记,详细讲解请购买原版书籍(绝对物超所值).---- ...
- Xamarin iOS教程之页面控件
Xamarin iOS教程之页面控件 Xamarin iOS 页面控件 在iPhone手机的主界面中,经常会看到一排小白点,那就是页面控件,如图2.44所示.它是由小白点和滚动视图组成,可以用来控制翻 ...
- GPU安装
安装驱动 https://developer.nvidia.com/cuda-downloads?target_os=Linux&target_arch=x86_64&target_d ...
- luogu P1663 山
题目链接 luogu P1663 山 题解 只需要求出下凸包的最低点就好了 显然是由两个斜率相反的直线相交来的 盼下最低点为直线的情况 代码 #include<cstdio> #inclu ...
- bzoj4456: [Zjoi2016]旅行者
题目链接 bzoj4456: [Zjoi2016]旅行者 题解 网格图,对于图分治,每次从中间切垂直于长的那一边, 对于切边上的点做最短路,合并在图两边的答案. 有点卡常 代码 #include< ...
- TreeMap(红黑树)源码分析
1. HashMap.Entry(红黑树节点) private static final boolean RED = false; private static final boolean BLACK ...
- 【学习笔记】python2和python3的input()
python2中的input()只接受变量作为传入值,非变量内容会报错. >>> user=input("Enter your name:") Enter you ...
- Java删除ArrayList中的重复元素
Java删除ArrayList中的重复元素的2种方法 ArrayList是Java中最常用的集合类型之一.它允许灵活添加多个null元素,重复的元素,并保持元素的插入顺序.在编码时我们经常会遇到那种必 ...