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 ...
随机推荐
- P1020 导弹拦截 dp 树状数组维护最长升序列
题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹 ...
- 常见Java库漏洞汇总
1.ActiveMQ 反序列化漏洞(CVE-2015-5254) ref:https://www.nanoxika.com/?p=408 Apache ActiveMQ是美国阿帕奇(Apache)软件 ...
- javascript模拟flash头像裁切上传
是的,jq已经有类似的插件了,或者干脆用flash算了,为什么我还要自己写?因为造(wo)轮(bu)子(hui)也(flash)是一个学习的过程,轮子不会造,将来怎么造飞机?先来一张最终效果图: 一. ...
- springmvc配置MappingJackson2HttpMessageConverter实现属性驼峰和下划线的转换
需求 php调用java接口时,因为php那边的属性都是下划线风格,java这边的属性都是驼峰的风格.配置springmvc的json转换,在requestBody的时候(调用对象的set 方法)将j ...
- eclipse launching workspace太慢的解决方法
这几天eclipse调试Android项目的时候反应超慢,右下显示launching workspace就不怎么动了,今天终于卡的受不了了,在网上搜了写方法,设置了下总算好点了,现在把方法贴出来,跟大 ...
- [转]eclipse转idea, 快捷键设置
原文地址: eclipse转idea, 快捷键设置 设置快捷键的途径: 打开idea的配置,找到Keymap,设置为eclipse 另外还要手动设置某些快捷键 上下移动 点击类打开 代码提示 查询 ...
- 【BZOJ-2063】我爸是李刚 数位dp 好题
2063: 我爸是李刚 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 139 Solved: 72[Submit][Status][Discuss] ...
- MySQL 集群
MySQL Galera介绍 主要功能: 同步复制 真正的multi-master,即所有节点可以同时读写数据库 自动的节点成员控制,失效节点自动被清除 新节点加入数据自动复制 真正的并行复制,行级 ...
- UVALive 6907 Body Building tarjan
Body Building 题目连接: https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8 ...
- vue项目开发之v-for列表渲染的坑
不知道大家在用vue开发的过程中有没有遇到过在使用v-for的时候会出现大片的黄色警告,比如下图: 其实这是因为没有写key的原因 :key是为vue的响应式渲染提供方法,在列表中单条数据改变的情况下 ...