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 ...
随机推荐
- laravel5 session的基本使用
配置session配置文件位于config/session.hpp 默认情况下使用session驱动为文件驱动,在生产环境中,建议使用memcache或者redis驱动以便获取更快的session性能 ...
- ubantu下如何完全彻底卸载mysql(转)
ubantu下如何完全彻底卸载mysql https://blog.csdn.net/wszll_Alex/article/details/46277681 第1步 依次执行下面的语句 1 sud ...
- .NET工作准备--03进阶知识
(已过时) 高级特性,多线程编程,单元测试; 第一部分 .net高级特性 1.委托:提供安全的函数回调机制; *基本原理:与C++中的函数指针相似;安全--它和其他所有.net成员一样是一种类型,任何 ...
- MySQL数据库之视图
1 引言 为了简化复杂SQL语句编写,以及提高数据库安全性,MySQL数据库视图特性.视图是一张虚拟表,不在数据库中以储存的数据值形式存在.在开发中,开发者往往只对某些特定数据和所负责的特定任务感兴趣 ...
- Nmap扫描教程之基础扫描详解
Nmap扫描教程之基础扫描详解 Nmap扫描基础扫描 当用户对Nmap工具了解后,即可使用该工具实施扫描.通过上一章的介绍,用户可知Nmap工具可以分别对主机.端口.版本.操作系统等实施扫描.但是,在 ...
- 最短路径:(Dijkstra & Floyd)
Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Di ...
- Vmaware复制后的虚拟机不能上网问题解决
最近在vmware上安装了一个xp虚拟机,想同时运行两个这样的虚拟机,于是想到了复制,将原来的虚拟机文件夹复制下来,然后在vmware中打开该文件扩展名为.vmx的虚拟机即可,但是发现却无法上网. 原 ...
- bzoj 2809 可并堆维护子树信息
对于每个节点,要在其子树中选尽量多的节点,并且节点的权值和小于一个定值. 建立大根堆,每个节点从儿子节点合并,并弹出最大值直到和满足要求. /***************************** ...
- Linux——多线程下解决生产消费者模型
我们学习了操作系统,想必对生产消费者问题都不陌生.作为同步互斥问题的一个经典案例,生产消费者模型其实是解决实际问题的基础模型,解决很多的实际问题都会依赖于它.而此模型要解决最大的问题便是同步与互斥.而 ...
- Regex.Split
private static List<int> GetThemeIds(string themeList) { const string split = "!===!" ...