(二)nio缓冲区之Buffer写与读

在Buffer开辟了一块缓存之后,则可以对该缓存进行读写操作:

进行开辟一块字节缓冲区,进行字节读写操作:

ByteBuffer buffer = ByteBuffer.allocate(10); //在JVM内存中开辟了一块10字节的缓冲区

//ByteBuffer buffer = ByteBuffer.allocateDirect(10); //在操作系统内存中开辟了一块10字节的缓冲区

一、写操作:

    buffer.put((byte)'H').put((byte)'e').put((byte)'l').put((byte)'l').put((byte)'o');

//或者buffer.put("Hello".getByte());

进行上述操作之后,buffer中的内容信息:

(二)nio缓冲区之Buffer写与读

如果想在不丢失位置的情况下,进行一些更改的话,可以使用put的重载方法,如将Hello改写成Mello:

buffer.put(0,(byte)'M'); //将缓冲区中第0个位置的字节改成'M'。

修改后的buffer如下图所示:

(二)nio缓冲区之Buffer写与读


二、翻转(翻转之后进行读操作):

Buffer类中红的flip()方法将一个能够继续添加数据元素的填充状态的缓冲区翻转成一个准备读出元素的释放状态。翻转之后缓冲区的内容如下所示:

(二)nio缓冲区之Buffer写与读

注:如果将缓冲区进行翻转两次或多次,缓冲区中的实际大小会变成0,flip()方法源码如下:

(二)nio缓冲区之Buffer写与读

何时进行翻转呢?

当要查看缓冲区中的数据时,需要进行翻转,即进行get()操作之前。

一旦缓冲区对象完成了填充并释放,它就可以被重新使用了。clear()函数将缓冲区重置为空状态,它并不改变缓冲区中的任何数据元素,而是仅仅将上界设置成0而已。

(二)nio缓冲区之Buffer写与读

三、数据的批量读取:

缓冲区的设计目的就是为了能高效的传输数据。有两种高效的get()方法(一次可读取多个数据)可供从缓冲区到数组进行数据读取。

第一种:只将一个数组作为参数,将一个缓冲区的内容复制到给定的数组中(省略长度意味着整个数组都会被填满)。

第二种:使用offset和length参数来指定目标数组的子区间。

批量移动总是具有指定的长度,即:要求移动固定数量的数据元素。

buffer.get(byte[] buf); 等价于 buffer.get(byte[] buf, 0, buf,length);

buffer.get(byte[] buf);意味着整个buf数组都会被填充,如果缓冲区中的数据不能够完全被填满,则会抛出异常:

(二)nio缓冲区之Buffer写与读

如果不想定义缓冲区大小的数组进行读取数据操作(假设定义小于缓冲区大小的数组),可以试用一下方式进行读取:

(二)nio缓冲区之Buffer写与读

当然最直接的办法就是定义一个缓冲区数据长度的数组读取数据,这样一次性即可读取完缓冲区中的数据:

(二)nio缓冲区之Buffer写与读

这样的优点是一次性读取完缓冲区的数据,缺点是是假如缓冲区中的数据很大,一次性读取缓冲区的数据意味着需要定义一个和缓冲区数据一样大的数组,可能会造成内存溢出的风险。





以下是一个完整的例子读写例子:

(二)nio缓冲区之Buffer写与读