io.netty.util.ReferenceCounted
html
此接口表明一个引用计数的对象,此对象须要显示的释放.java
当一个ReferenceCounted
对象被实例化的时候,该对象的引用数量就是1,调用retain()
方法会增长引用数量,调用 release()
方法会减小引用数量,若是引用数量减小到0,该对象就须要显示释放掉。访问释放掉的对象一般会致使访问冲突。web
若是实现ReferenceCounted
接口的对象是一个包含一样实现ReferenceCounted
接口的对象的容器。当容器的引用数量变为0的时候,容器中的对象也要经过release()
方法来释放掉。api
主要方法:数组
int refCnt(); //返回当前对象的引用数量,若是返回零,说明当前对象已经被释放掉了
ReferenceCounted retain();//引用数量增长1
ReferenceCounted retain(int increment);//引用计数增长给定值increment
ReferenceCounted touch();\\此方法记录对象的当前访问位置,主要用来调试。若是肯定当前对象内存泄露,经过此操做记 \\录的信息将经过ResourceLeakDetector提供给你
ReferenceCounted touch(Object hint);\\此方法记录对象的当前访问位置并附加一个hint对象,主要用来调试。若是 \\肯定当前对象内存泄露,经过此操做记录的信息将经过ResourceLeakDetector提供给你
boolean release();\\引用计数减1,若是引用计数变为0了,则显示的释放掉该对象,当且仅当引用计数变为0且该对象已 \\被释放掉才返回ture,不然返回false
boolean release(int decrement);\\引用计数减小给定值decrement,若是引用计数变为0了,则显示的释放掉该对象, 当且仅当引用计数变为0且该对象已被释放掉才返回ture,不然返回false
io.netty.buffer.ByteBuf安全
这是一个随机和顺序访问的序列其包含0或者多个字节,此接口为一个或者多字节数组和NIO buffers提供了一个抽象试图app
建立buffer dom
建议使用辅助方法建立一个新的缓冲区不要调用具体实现的构造函数。
函数
随进访问索引 工具
就像普通的byte数组同样,ByteBuf使用基于0的索引,也就是第一个的索引是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使如何被两个指针分割成三个区域的:
+-------------------+------------------+------------------+ | discardable bytes | readable bytes | writable bytes | | | (CONTENT) | | +-------------------+------------------+------------------+ | | | | 0 <= readerIndex <= writerIndex <= capacity
discardable bytes表明可废弃的区域,readable bytes代码可读区域,writable bytes表明可写区域 readerIndex表明读的起点,writerIndex表明写的起点,capacity表明容量
可读区域(实际内容)
这个区域存储的是实际的数据或者叫有效的数据. 任何以read或者skip开头的操做(任何是指本类中的任何方法)都会获得或者跳过当前readerIndex指示的数据,而且readerIndex会根据读取或者跳过的字节数自增。若是读取 操做的参数也是一个Byte而且没有指定目标ByteBuf的起始index,则该参数ByteBuf的writerIndex也要跟着一块儿增加。
若是没有足够的数据供读取则报IndexOutOfBoundsException。新分配、wrapped或者拷贝的buffer,其readerIndex是0.相关读取操做以下:
// Iterates the readable bytes of a buffer. ByteBuf buffer = ...; while (buffer.readable()) { System.out.println(buffer.readByte()); }
可写数据区域
此区域是未定义的区域也就是须要往里面写数据的区域。任何以write开始的操做(任何是指本类中的任何方法)将会从writerIndex开始写数据,而且writerIndex会根据写入的数量增长。若是write操做的参数也是一个ByteBuf而且没有制定源Buff的开始index, 那么该参数ByteBuf的readerInx也要跟着一块儿增加.
若是没有足够的空间供写入报IndexOutOfBoundsException
,新分配的buffer的writerIndex是0. wrapped 或者copy的 bufferwriterIndex 等于capacity。写入操做代码:
// Fills the writable bytes of a buffer with random integers. ByteBuf buffer = ...; while (buffer.maxWritableBytes() >= 4) { buffer.writeInt(random.nextInt()); }
可废弃区域
这个区域包含的是经过读操做读完的数据区域.初始状态这个区域的大小是0
, 随着读操做的调用这个区域会增加到writerIndex的大小. 读过的数据能够经过调用discardReadBytes()方法回收该区域,该方法的功能以下
:
BEFORE discardReadBytes()//操做前 +-------------------+------------------+------------------+ | discardable bytes | readable bytes | writable bytes | +-------------------+------------------+------------------+ | | | | 0 <= readerIndex <= writerIndex <= capacity AFTER discardReadBytes()//操做后 +------------------+--------------------------------------+ | readable bytes | writable bytes (got more space) | +------------------+--------------------------------------+ | | | readerIndex (0) <= writerIndex (decreased) <= capacity
须要注意的是,不能保证可写区域的数据内容,可写区域的内容多数状况下不会跟着移动,甚至有可能被不一样的数据填充,这依赖于具体的buffer实现。
清空缓冲索引
你能够经过调用clear()方法来将
readerIndex
和 writerIndex
设置为 0
. 可是不会清除内容,而只是重置了两个指针. 注意这里的clear()方法语义和java.nio.Buffer.clear()语义是不同的。
BEFORE clear() +-------------------+------------------+------------------+ | discardable bytes | readable bytes | writable bytes | +-------------------+------------------+------------------+ | | | | 0 <= readerIndex <= writerIndex <= capacity AFTER clear() +---------------------------------------------------------+ | writable bytes (got more space) | +---------------------------------------------------------+ | | 0 = readerIndex = writerIndex <= capacity
search相关操做
对于简单的字节搜索,使用 indexOf(int, int, byte)
和 bytesBefore(int, int, byte)
. bytesBefore(byte)
. 对于复杂的搜索使用 forEachByte(int, int, ByteBufProcessor)
方法,该方法须要一个 ByteBufProcessor
的实现类.
标记和充值 (mark reset)
每一个buffer有两个marker indexes. 一个用来存储 readerIndex
另外一个用来存储 writerIndex
. 能够经过调用reset方法重置,其工做方式相似于InputStream中的mark和reset方法,不一样的是其没有readlimit参数.
派生缓冲区(Derived buffers)
你能够经过调用方法duplicate()
, slice()
or slice(int, int)
来根据现有buffer建立一个试图(view) . 一个派生的buffer会有一个独立的readerIndex
, writerIndex
和 marker indexes,同时会共享内部数据,这和Java NIO同样.若是要完整拷贝一个buffer,须要调用copy()
方法.
转换成现有的JAVA类型
若是ByteBuf内部实现是一个byte[], 能够经过调用array()
方法来访问数组. 判断是不是byte[]能够调用 hasArray()
方法.
经过调用nioBuffer()
方法能够获得一个NIO buffer,判断可否进行转换能够调用nioBufferCount()
方法.
能够调用提供的多个 toString(Charset)
方法将 ByteBuf
转换为 String
. 须要注意的是,toString()
不是转换方法,而是继承Object的toString()方法
参考 ByteBufInputStream
和 ByteBufOutputStream
.
io.netty.buffer.ByteBufAllocator
该接口的实现类负责建立buffer,接口实现类必须是线程安全的。
发送接收的数据包
实现bytebuf的一个骨架
ByteBufAllocator
的骨架
Bytebuf的一个抽象基类,其主要功能是实现了可以封装另外一个Bytebuf
ByteBuf的一个抽象基类,主要功能是实现了引用计数的功能,即ReferenceCounted借口的功能(retain和release、touch方法)
继承了InputStream类,该类能够从ByteBuf中读取数据,对该对象进行读操做的时候内部buffer的readerIndex也会增长,须要注意的是读取的字节数量在初始化该对象的时候已经肯定了(构造函数内部,初始化的时候已经和设置了长度),后面在对该buffer写数据,对该对象来说,不会读到。
改流仍是DataInput
借口,字节的序列并不老是大端序列(big endian),这取决于内部buffer实现
继承了OutputStream类,该类能够向ByteBuf中写数据,对该对象进行写操做的时候内部buffer的writerindex也会增长,改流仍是DataOutput
借口,字节的序列并不老是大端序列(big endian),这取决于内部buffer实现
这是一个处理ByteBuf对象的一些方法的工具类.
这是一个虚拟bufer,其实是一个组合buffer,其内部封装了多个buffer,其功能就是将多个buffer组合成一个buffer,推荐使用ByteBufAllocator.compositeBuffer()
或者Unpooled.wrappedBuffer(ByteBuf...)来建立CompositeByteBuf对象,不要直接调用构造函数来建立对象
ByteBufHolder
的默认实现,期功能就是把数据存储在bytebuf中
一个派生buffer,简单的把全部的数据访问请求发送给内部的buffer。简易经过ByteBuf.duplicate()
方法来建立该对象。该对象与其内部bufer共享数据,只不过两者的readerindex和writerindex是独立的。
这是一个空的ByteBuf,容量是0
带缓冲的ByteBufAllocator
这个一个派生buffer,他禁止写操做发送给内部buffer,简易经过 Unpooled.unmodifiableBuffer(ByteBuf)
方法来建立对象
io.netty.buffer.SliceByteBuf
一个派生buffer,他的功能是仅仅暴露内部buffer的一个自区域,就是切片,推荐经过ByteBuf.slice()
andByteBuf.slice(int, int)
方法来建立对象
一个包装buffer,其功能是交换bytebuf的字节序列,即大端序列和小端序列的转换
io.netty.buffer. Unpooled
带缓冲的ByteBufAllocator
基于NIO ByteBuffer
的ByteBuf,推荐经过调用Unpooled.directBuffer(int)或者
Unpooled.wrappedBuffer(ByteBuffer)方法来建立对象
大端序列的java堆buffer实现
至关于一个工具类,能够建立Bytebuf