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 ...
随机推荐
- maven 不同环境打包命令
mvn clean package mvn clean package -Pdev mvn clean package -Ptest mvn clean package -Pproduct
- org.apache.maven.archiver.MavenArchiver.getManifest错误
eclipse导入新的maven项目时,pom.xml第一行报错: org.apache.maven.archiver.MavenArchiver.getManifest(org.apache.mav ...
- Qt代码创建分隔条
我们在使用Qt时,会发现在使用UI界面时可以添加窗口分隔条,但我们使用纯代码时却没有分隔条的类函数.这时候我们就需要手动添加,添加方式和Qt自定义标签按钮一样,下面我直接写代码.如果不知道怎么添加的, ...
- JAVA-Exception&Error
JAVA--Exception&Error 在万物皆对象的JAVA中,先让我们看看Exception和Error的地位吧:
- Ubuntu下登陆远程postgresql数据库
登陆公司远程postgresql:psql -h <host or remote id> -p <port> dbdame 如: psql -h aliyunsql_addr ...
- hdu 5762 Teacher Bo 暴力
Teacher Bo 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5762 Description Teacher BoBo is a geogra ...
- 将网桥的配置写进去/etc/sysconfig/network-scripts/ifcfg-xxx
有时候需要使用网桥命令比如brctl设置一些网桥的属性,而这些方式能否同样写进去配置文件使其永久开机生效. 答案是不行的,也同样找过Ubuntu的,其实Ubuntu可以实现,参考:http://man ...
- spring cloud 学习(10) - 利用springfox集成swagger
对绝大多数程序员而言,写接口文档是一件痛苦的事情,相对文档,他们更愿意写代码.最理想的情况就是:代码即文档!服务开发完成后,部署上去文档就自动生成,没错,这就是springfox + swagger要 ...
- leetcode第一刷_Unique Binary Search Trees
这道题事实上跟二叉搜索树没有什么关系,给定n个节点,让你求有多少棵二叉树也是全然一样的做法.思想是什么呢,给定一个节点数x.求f(x),f(x)跟什么有关系呢,当然是跟他的左右子树都有关系.所以能够利 ...
- ASP.NET Web API接受AngualrJS的QueryString的两种方式
ASP.NET Web API如何接受来自AngualrJS的QueryString呢?本篇体验两种方式. 第一种方式:http://localhost:49705/api/products?sear ...