ByteBuffer学习

背景: 项目中学习使用了Java原生NIO,这时则需要通过ServerSocketChannel的accept()方法获取到客户端的SocketChannel,再使用客户端SocketChannel直接进行读写。但SocketChannel.read(ByteBuffer dst)和SocketChannel.write(ByteBuffersrc)的方法中的参数则都变为了java.nio.ByteBuffer,该类型就是JavaNIO对byte数组的一种封装,其中包括了很多基本的操作,在此记录一下备忘。

ByteBuffer包含几个基本的属性:

position:当前的下标位置,表示进行下一个读写操作时的起始位置;

limit:结束标记下标,表示进行下一个读写操作时的(最大)结束位置;

capacity:该ByteBuffer容量;

mark: 自定义的标记位置;

1.    初始化


2.    写数据


      但是当想要写入的数据长度大于ByteBuffer当前剩余的长度时,则会抛出BufferOverflowException异常,剩余长度的定义即为limit与position之间的差值(即 limit - position)。如上述例子中,若再执行buffer.put(new byte[12]);就会抛出BufferOverflowException异常,因为剩余长度为11。可以通过调用ByteBuffer.remaining();查看该ByteBuffer当前的剩余可用长度。

3.    读数据



get(),getInt()position向后移动读取的长度


4.    复位



rewind()方法常常用于字节数组的完整拷贝

实际应用中更常用的是flip()方法,该方法不仅将position复位为0,同时也将limit的位置放置在了position之前所在的位置上,这样position和limit之间即为新读取到的有效数据。

5.    字节序处理

静态方法ByteOrder.nativeOrder()可以获取到当前机器使用的字节序,使用ByteBuffer中的order()方法即可获取该buffer所使用的字节序buffer.order(ByteOrder.LITTLE_ENDIAN)

6.    继续写入数据

ByteBuffer往往是非阻塞式的,故不能确定新的数据是否已经读完,但这时候依然可以调用ByteBuffer的compact()方法切换到读取模式。该方法就是将 position 到 limit 之间还未读取的数据拷贝到 ByteBuffer 中数组的最前面,然后再将 position 移动至这些数据之后的一位,将 limit 移动至 capacity。这样 position 和 limit 之间就是已经读取过的老的数据或初始化的数据


上诉总结以基本满足再开发中的需求,下面链接是自己的学习地址,https://blog.csdn.net/mrliuzhao/article/details/89453082

你可能感兴趣的:(ByteBuffer学习)