1、Buffer缓冲区详细介绍
在java NIO套件中,Buffer的作用主要就是用来存取数据的,Buffer是一个抽象类,其类图主要如下:
每一个Buffer实现对应着这种Buffer只能存储此种数据,例如BytreBuffer就只能存储字节数据,这些缓冲区都是用其实现类的静态方法allocate()来进行分配,案例如下:
其中1024表示分配的缓冲区的容量,一旦分配就不能修改容量。
ByteBuffer allocate = ByteBuffer.allocate(1024);
2、缓冲区Buffer的核心方法
2.1、put()方法:用于将数据存储到缓冲区中。
2.2、get()方法:用于从缓冲区中获取数据。
2.3、flip()方法:切换缓冲区的读写模式,就是进行反转。
2.4、mark()方法:标记当前position,然后是可以使用reset方法进行重置position到之前mark标记的position。
2.5、reset()方法:重置当前position到mark标记的位置。
2.6、hasRemaining()方法:返回当前缓冲区中还有没有剩余的数据。
3、Buffer类的核心属性
在Buffer中定义了很多属性,我们主要关注的有一下4个重要属性:
private int mark = -1;
private int position = 0;
private int limit;
private int capacity;
3.1、capacity:容量,表示缓冲区中能存储的最大容量,一旦声明就不能改变。
3.2、limit:界限,表示缓冲中可以操作数据的大小。
3.3、position:位置,缓冲区中正在操作的位置。
3.4、mark:标记,表示几率==记录当前position值,可以通过reset()恢复到mark标记的位置。
0 <= mark <= position <= limit <= capacity
4、测试案例
@Test
public void test1() throws UnsupportedEncodingException {
String str = "abcde";
ByteBuffer buffer = ByteBuffer.allocate(10);
System.out.println("=============调用allocate(10)后属性值=========");
System.out.println("capacity:" + buffer.capacity());
System.out.println("limit:" + buffer.limit());
System.out.println("position:" + buffer.position());
System.out.println("==============调用put()方法存入abcde字符串后==");
buffer.put(str.getBytes("UTF-8"));
System.out.println("capacity:" + buffer.capacity());
System.out.println("limit:" + buffer.limit());
System.out.println("position:" + buffer.position());
System.out.println("==============调用get()方法读取ab字符串后=====");
buffer.flip();//先反转缓冲区
byte[] bytes = new byte[buffer.limit()];
buffer.get(bytes);
System.out.println(new String(bytes,0, bytes.length));
System.out.println("capacity:" + buffer.capacity());
System.out.println("limit:" + buffer.limit());
System.out.println("position:" + buffer.position());
System.out.println("==============调用rewind()置为可重复读==========");
buffer.rewind();
System.out.println("capacity:" + buffer.capacity());
System.out.println("limit:" + buffer.limit());
System.out.println("position:" + buffer.position());
System.out.println("==============调用clear()置清空缓冲区==========");
buffer.clear();//缓冲区虽然被清空了,但是缓冲区中的数据依然存在,只是处于"被遗忘"的状态
System.out.println("capacity:" + buffer.capacity());
System.out.println("limit:" + buffer.limit());
System.out.println("position:" + buffer.position());
System.out.println((char) buffer.get());
}
测试案例输出:
=============调用allocate(10)后属性值=========
capacity:10
limit:10
position:0
==============调用put()方法存入abcde字符串后==
capacity:10
limit:10
position:5
==============调用get()方法读取ab字符串后=====
abcde
capacity:10
limit:5
position:5
==============调用rewind()置为可重复读==========
capacity:10
limit:5
position:0
==============调用clear()置清空缓冲区==========
capacity:10
limit:10
position:0
a
Process finished with exit code 0
5、测试mark()方法:
@Test
public void test2(){
String str = "abcde";
ByteBuffer buffer = ByteBuffer.allocate(10);
buffer.put(str.getBytes());
//反转
buffer.flip();
//读写两个byte
byte[] bytes = new byte[2];
buffer.get(bytes);
System.out.println(new String(bytes));
//标记当前操作位置 2
buffer.mark();
System.out.println("mark 的 position:" + buffer.position());
byte b = buffer.get();
System.out.println((char) b);
System.out.println("再读取一个byte后的position:" + buffer.position());
buffer.reset();
System.out.println("reset后的position:" + buffer.position());
byte c = buffer.get();
System.out.println((char) c);
System.out.println("reset后再读取一个byte后的position:" + buffer.position());
}
输出 :
ab
mark 的 position:2
c
再读取一个byte后的position:3
reset后的position:2
c
reset后再读取一个byte后的position:3
Process finished with exit code 0