Buffer是一个对象,它包含一些要写入或者读取的数据。在NIO类库中加入Buffer对象,体现了新库与原IO的一个重要的区别。在面向流的IO中,可以将数据直接写入或者读取到Stream对象中。在NIO库中,所有的数据都是用缓冲区处理的(读写)。缓冲区实质上是一个数组,通常它是一个字节数组(ByteBuffer),也可以使用其他类型的数组。这个数组为缓冲区提供了数据的访问读写等操作属性,如位置、容量、上限等概念,可以参考一下API文档。
Buffer类型:我们最常用的就是ByteBuffer,实际上每一种java的基本类型都对应着一种缓冲区(除了Boolean类型)
ByteBuffer、CharBuffer、ShortBuffer、IntBuffer、LongBuffer、FloatBuffer、DoubleBuffer。
下面我们以IntBuffer来举例怎么使用缓冲区,因为每一种Buffer的使用都是差不多滴。
//创建指定长度的缓冲区
IntBuffer buf = IntBuffer.allocate(10);
//positoin表示当前位置
buf.put(11); //添加后,position由0变为1
buf.put(22); //position位置: 1->2
buf.put(33); //position位置: 2->3
//flip方法会将position位置复位为0 也就是3->0
buf.flip();
System.out.println("使用flip复位后:"+buf);
System.out.println("缓冲区容量为:"+buf.capacity()); //容量一旦初始化后不允许改变(warp方法包裹数组除外)
System.out.println("缓冲区的限制为:"+buf.limit());//由于只装载了三个元素,所以可读取或者操作的元素为3,则limit=3
System.out.println("获取下标为1的元素:"+buf.get(1));
System.out.println("get(index)方法获取后,position位置不变:"+buf);
buf.put(1,12); //会覆盖原来index为1的值
System.out.println("put(index,change)方法添加后,position位置不变:"+buf);
for(int i=0;i
使用flip复位后:java.nio.HeapIntBuffer[pos=0 lim=3 cap=10]
缓冲区容量为:10
缓冲区的限制为:3
获取下标为1的元素:22
get(index)方法获取后,position位置不变:java.nio.HeapIntBuffer[pos=0 lim=3 cap=10]
put(index,change)方法添加后,position位置不变:java.nio.HeapIntBuffer[pos=0 lim=3 cap=10]
11 12 33 buf对象遍历之后:java.nio.HeapIntBuffer[pos=3 lim=3 cap=10]
int[] arr = new int[]{1,2,3};
IntBuffer buf = IntBuffer.wrap(arr);
System.out.println("wrap(arr)方法的缓冲区:"+buf);
buf.put(1, 6); //将缓冲区index为1的数据修改为6
System.out.println(arr[1]); //发现,数组indexi为1也确实被改为6了
执行结果:
wrap(arr)方法的缓冲区:java.nio.HeapIntBuffer[pos=0 lim=3 cap=3]
6
wrap(arr,offset,length)方法的缓冲区:java.nio.HeapIntBuffer[pos=0 lim=2 cap=3]
需要注意的是:我们可以看到wrap方法如果带上包裹的初始位置和长度,那么litmit就会是可操作元素的个数,而不是被包裹数组的长度了
3、其他方法
IntBuffer buf = IntBuffer.allocate(10);
int[] arr = new int[]{1,2,3};
buf.put(arr);
System.out.println(buf);
//复制方法
IntBuffer buf2 = buf.duplicate();
System.out.println("复制后的新缓冲区:"+buf2);
//设置position的方法
System.out.println("设置position前的缓冲区:"+buf);
//可读数据是直接调用get()方法能获取饿数据,而不是get(index)方法
//此时因为调用过put将数组添加到缓冲区,而数组的个数是3,所以position此时肯定是为3的
//而IntBuffer初始化的长度为10,所以可读数据个数应该为7
System.out.println("重新设置position之前的可读数据个数:"+buf.remaining());
System.out.println();
buf.position(1);
System.out.println("设置position后的缓冲区:"+buf);
//重新设置后的position为1,所以可读数据个数为9
System.out.println("重新设置position之后的可读数据个数:"+buf.remaining());
//将缓冲区的数据放入数组里面
int[] arr2 = new int[buf.remaining()];
buf.get(arr2);
//由于上面是重新设置position为1,所以是将1及1之后的元素放入数组里面
//所以数组里面会有9个元素
for(int i : arr2){
System.out.println(Integer.toString(i)+",");
}
执行结果:
java.nio.HeapIntBuffer[pos=3 lim=10 cap=10]
复制后的新缓冲区:java.nio.HeapIntBuffer[pos=3 lim=10 cap=10]
设置position前的缓冲区:java.nio.HeapIntBuffer[pos=3 lim=10 cap=10]
重新设置position之前的可读数据个数:7
设置position后的缓冲区:java.nio.HeapIntBuffer[pos=1 lim=10 cap=10]
重新设置position之后的可读数据个数:9
2,
3,
0,
0,
0,
0,
0,
0,
0,