netty中的ByteBuf是基于java.nio的ByteBuffer扩展的,主要是因为nio中的ByteBuffer中存在一些使用上的不方便,比如:1.创建的ByteBuffer对象是固定容量的,当超过容量便会报错。2.只有一个标识位置的指针,读写数据的时候需要手动调用flip()和rewind()方法,使用稍有不慎便会造成程序报错。当然在一些官方文档上面关于这个的描述还有其他一些问题,这里就不再详述了。
接下来讲讲netty中的ByteBuf吧,看看这个是如何解决上面存在的问题以及又有哪些拓展的功能呢?
1.ByteBuf的工作原理:
首先ByteBuf依然是byte数组的缓冲区,它的基本功能同jdk的ByteBuffer,如下:
(1)7种java基础类型,byte数组,ByteBuffer(ByteBuf)等的读写;
(2)缓冲区自身的copy(拷贝)与slice(截取)等;
(3)设置网络字节序;
(4)构造缓冲区实例;
(5)操作位置指针等方法。
以上的功能具体对应ByteBuf中的哪些方法容以后在来补充吧。
ByteBuf通过两个位置指针来协助缓冲区的读写操作,读操作使用readerIndex,写操作使用writerIndex,readerIndex与writerIndex一开始都是0,随着数据的写入writerIndex会增加,读取数据会使readerIndex增加,但是readerIndex永远小于writerIndex。在读取数据后,0~readerIndex之间的数据就被视为discard,调用discardReadBytes方法可以释放这部分的空间,这个作用就有点像nio ByteBuffer中的compact方法。另外readerIndex与writerIndex方法之间的数据是可读的,等价于nio ByteBuffer中的position和limit之间的数据。writerIndex与capacity之间的空间是可写的,等价于ByteBuffer中的limit和capacity之间的可用空间。
由于读操作不修改writerIndex的值,写操作修改readerIndex的值,这样读写之间就不需要调整位置指针,这极大的简化了缓冲区的读写操作,避免由于遗漏或者不熟悉flip操作导致的功能异常。
接下来继续讨论ByteBuf如何实现动态扩展的。通常情况下,当我们对ByteBuffer进行put操作的时候,都要校验当前ByteBuffer的可写空间是否足够,如果不够,需要将当前的ByteBuffer拷贝到一个更到容量的ByteBuffer中去,然后将先前的ByteBuffer释放掉,具体代码如下:
if(this.buffer.remaining() < needSize) { int toBeExtSize = needSize > 128 ? needSize : 128; ByteBuffer tmpBuffer = ByteBuffer.allocate(this.buffer.capacity+toBeExtSize); this.buffer.flip(); tmpBuffer.put(this.buffer); this.buffer = tmpBuffer; }
从上面的代码可以看出,每进行一次put操作的时候都要进行一次可用空间的校验,这在平时的代码实现上很是麻烦,稍有不慎还有可能引发其他问题。为了解决这个问题,netty ByteBuf对nio ByteBuffer的write操作进行了封装,由这个封装后的write方法进行校验当前buffer的可用空间是否足够,并进行扩容。具体代码如下:
@Override public ByteBuf ensureWritable(int minWritableBytes) { if (minWritableBytes < 0) { throw new IllegalArgumentException(String.format( "minWritableBytes: %d (expected: >= 0)", minWritableBytes)); } if (minWritableBytes <= writableBytes()) { return this; } if (minWritableBytes > maxCapacity - writerIndex) { throw new IndexOutOfBoundsException(String.format( "writerIndex(%d) + minWritableBytes(%d) exceeds maxCapacity(%d): %s", writerIndex, minWritableBytes, maxCapacity, this)); } // Normalize the current capacity to the power of 2. int newCapacity = calculateNewCapacity(writerIndex + minWritableBytes); // Adjust to the new capacity. capacity(newCapacity); return this; }
@Override public ByteBuf writeShort(int value) { ensureAccessible(); ensureWritable(2); _setShort(writerIndex, value); writerIndex += 2; return this; } @Override public ByteBuf writeMedium(int value) { ensureAccessible(); ensureWritable(3); _setMedium(writerIndex, value); writerIndex += 3; return this; } @Override public ByteBuf writeInt(int value) { ensureAccessible(); ensureWritable(4); _setInt(writerIndex, value); writerIndex += 4; return this; }
从上面的代码可以看出,ByteBuf在为确保可用空间的足够,在每次进行写操作的时候都会调用一次ensureWritable(int)方法来保证不会出现容量不够的情况,这样我们在实际应用开发的时候就不需要考虑容量的问题,只需要专心在我们具体往ByteBuf中写什么东西等逻辑上面了。
前面大致总结了ByteBuf的原理,接下来看看api吧,ByteBuf具体给我们提供了那些方法供使用呢 ?
1.顺序读操作(read)
ByteBuf的read操作类似于ByteBuffer的get操作,
相关推荐
赠送jar包:transport-netty4-client-5.5.1.jar; 赠送原API文档:transport-netty4-client-5.5.1-javadoc.jar; 赠送源代码:transport-netty4-client-5.5.1-sources.jar; 赠送Maven依赖信息文件:transport-netty...
赠送jar包:netty-transport-native-unix-common-4.1.73.Final.jar; 赠送原API文档:netty-transport-native-unix-common-4.1.73.Final-javadoc.jar; 赠送源代码:netty-transport-native-unix-common-4.1.73....
赠送jar包:netty-transport-native-unix-common-4.1.68.Final.jar; 赠送原API文档:netty-transport-native-unix-common-4.1.68.Final-javadoc.jar; 赠送源代码:netty-transport-native-unix-common-4.1.68....
赠送jar包:netty-transport-classes-epoll-4.1.73.Final.jar; 赠送原API文档:netty-transport-classes-epoll-4.1.73.Final-javadoc.jar; 赠送源代码:netty-transport-classes-epoll-4.1.73.Final-sources.jar;...
赠送jar包:netty-transport-native-unix-common-4.1.74.Final.jar; 赠送原API文档:netty-transport-native-unix-common-4.1.74.Final-javadoc.jar; 赠送源代码:netty-transport-native-unix-common-4.1.74....
赠送jar包:netty-transport-classes-epoll-4.1.74.Final.jar; 赠送原API文档:netty-transport-classes-epoll-4.1.74.Final-javadoc.jar; 赠送源代码:netty-transport-classes-epoll-4.1.74.Final-sources.jar;...
赠送jar包:netty-transport-classes-epoll-4.1.73.Final.jar; 赠送原API文档:netty-transport-classes-epoll-4.1.73.Final-javadoc.jar; 赠送源代码:netty-transport-classes-epoll-4.1.73.Final-sources.jar;...
赠送jar包:netty-resolver-dns-4.1.65.Final.jar; 赠送原API文档:netty-resolver-dns-4.1.65.Final-javadoc.jar; 赠送源代码:netty-resolver-dns-4.1.65.Final-sources.jar; 赠送Maven依赖信息文件:netty-...
赠送jar包:netty-codec-mqtt-4.1.73.Final.jar; 赠送原API文档:netty-codec-mqtt-4.1.73.Final-javadoc.jar; 赠送源代码:netty-codec-mqtt-4.1.73.Final-sources.jar; 赠送Maven依赖信息文件:netty-codec-...
赠送jar包:netty-transport-native-unix-common-4.1.73.Final.jar; 赠送原API文档:netty-transport-native-unix-common-4.1.73.Final-javadoc.jar; 赠送源代码:netty-transport-native-unix-common-4.1.73....
赠送jar包:reactor-netty-core-1.0.15.jar; 赠送原API文档:reactor-netty-core-1.0.15-javadoc.jar; 赠送源代码:reactor-netty-core-1.0.15-sources.jar; 赠送Maven依赖信息文件:reactor-netty-core-1.0.15....
赠送jar包:netty-codec-haproxy-4.1.73.Final.jar; 赠送原API文档:netty-codec-haproxy-4.1.73.Final-javadoc.jar; 赠送源代码:netty-codec-haproxy-4.1.73.Final-sources.jar; 赠送Maven依赖信息文件:netty-...
赠送jar包:transport-netty4-client-6.3.0.jar; 赠送原API文档:transport-netty4-client-6.3.0-javadoc.jar; 赠送源代码:transport-netty4-client-6.3.0-sources.jar; 赠送Maven依赖信息文件:transport-netty...
赠送jar包:reactor-netty-http-1.0.15.jar; 赠送原API文档:reactor-netty-http-1.0.15-javadoc.jar; 赠送源代码:reactor-netty-http-1.0.15-sources.jar; 赠送Maven依赖信息文件:reactor-netty-...
赠送jar包:netty-codec-mqtt-4.1.74.Final.jar; 赠送原API文档:netty-codec-mqtt-4.1.74.Final-javadoc.jar; 赠送源代码:netty-codec-mqtt-4.1.74.Final-sources.jar; 赠送Maven依赖信息文件:netty-codec-...
netty-socketio-netty-socketio-2.0.6 ,Socket.IO 是一个库,可以在客户端和服务器之间实现低延迟, 双向和基于事件的通信:netty-socketio-netty-socketio-2.0.6.tar.gznetty-socketio-netty-socketio-2.0.6.zip
赠送jar包:transport-netty4-client-5.5.1.jar; 赠送原API文档:transport-netty4-client-5.5.1-javadoc.jar; 赠送源代码:transport-netty4-client-5.5.1-sources.jar; 赠送Maven依赖信息文件:transport-netty...
赠送jar包:netty-codec-dns-4.1.65.Final.jar; 赠送原API文档:netty-codec-dns-4.1.65.Final-javadoc.jar; 赠送源代码:netty-codec-dns-4.1.65.Final-sources.jar; 赠送Maven依赖信息文件:netty-codec-dns-...
赠送jar包:reactor-netty-http-1.0.11.jar; 赠送原API文档:reactor-netty-http-1.0.11-javadoc.jar; 赠送源代码:reactor-netty-http-1.0.11-sources.jar; 赠送Maven依赖信息文件:reactor-netty-...
赠送jar包:netty-resolver-dns-4.1.65.Final.jar; 赠送原API文档:netty-resolver-dns-4.1.65.Final-javadoc.jar; 赠送源代码:netty-resolver-dns-4.1.65.Final-sources.jar; 赠送Maven依赖信息文件:netty-...