目录:
java Nio(一) : Nio 和Io 的区别
java Nio(二): Buffer(缓冲区)的数据存取
java Nio(三):直接缓冲区 和 非直接缓冲区
java Nio(四) :通道(Channel)
java Nio(五) : 字符集:CharSet
从结构来看 Buffer就想 一个数组。可以保存多种类型的数据。他是一个抽象类。常用的子类是ByteBuffer,除了ByteBuffer 外,也可以操作其他基本类型,但是Boolean 除外。
/**
* 1,缓冲区(Buffer):在java NIO 中负责数据的存储。缓冲区就是数组。用于存储个中不同类型的数据。
* 根据数据类型的不同(boolean 除外) ,提供了对应的缓冲区:如byteBuffer,CharBuffer.....
*
* 上述的各种类型的缓冲区都是通过allocate()方法获取大小
*
* 2,缓冲区存取数据的核心方法:
* put() : 存入数据到缓冲区
* get() : 获取缓冲区中的数据
*
* 3,缓冲区中四个核心的属性:
* capacity : 容量,表示缓冲区的容量。声明后不能改变。
* limit : 界限,表示缓冲区中可以操作数据的大小。limit以后的数据不能进行读写
* position : 位置,表示缓冲区正在操作的位置
* mark : 标记,表示记录当前position的位置,可以通过reset()恢复到mark的位置
*
* 由此可以得出:mark <= position <= limit <= capacity
*/
下面看一下使用流程:
1,分配缓冲区大小,然后打印属性值。
//分配一个指定大小的缓冲区
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
System.out.println("---------------allocate-------------------");
System.out.println(byteBuffer.capacity());
System.out.println(byteBuffer.limit());
System.out.println(byteBuffer.position());
结果:
---------------allocate-------------------
1024
1024
0
图解:
2,往缓冲区中存入字节,打印属性值。
System.out.println("---------------put-------------------");
String str = "abcde";
byteBuffer.put(str.getBytes());
System.out.println(byteBuffer.capacity());
System.out.println(byteBuffer.limit());
System.out.println(byteBuffer.position());
结果:
---------------put-------------------
1024
1024
5
可以看到 下标从 0 走到了5.
3,切换到读取模式,打印属性值。
//切换到读取模式
byteBuffer.flip();
System.out.println("---------------filp-------------------");
System.out.println(byteBuffer.capacity());
System.out.println(byteBuffer.limit());
System.out.println(byteBuffer.position());
结果:
---------------filp-------------------
1024
5
0
图解:
由图可知,当切换到读取模式后,position执行了0,limit 指向了5。这意味着 读取的时候要从0开始,到5结束(不包含5),limit后面的数据不能进行读写。
4,使用get()方法对缓冲区内容进行读取,打印属性值。
//使用get() 对缓冲区的数据进行读取
System.out.println("---------------get-------------------");
byte[] bytes = new byte[byteBuffer.limit()];
byteBuffer.get(bytes);//将读取的数据存入bytes数组中,
System.out.println(new String(bytes,0,bytes.length));
System.out.println(byteBuffer.capacity());
System.out.println(byteBuffer.limit());
System.out.println(byteBuffer.position());
结果:
---------------get-------------------
abcde
1024
5
5
图解:
由图可知,进行读取后,position 指向了5。buffer的get方法也可以通过下表来获取缓冲区的数据,
但是请注意:通过下标获取的数据的时候 下标必须小于limit。而且通过下标获取数据后 position的位置不会发生改变。
5,rewind() 可重复读
byteBuffer.rewind();
System.out.println("---------------rewind-------------------");
System.out.println(byteBuffer.capacity());
System.out.println(byteBuffer.limit());
System.out.println(byteBuffer.position());
结果:
---------------rewind-------------------
1024
5
0
由打印的结果可以看出,position 指向了0,limit的值没变。说明可以从头进行读取了。
6,clear() 清空缓冲区。但是缓冲区中的数据还在,但是出于被遗忘状态。
//clear() 清空缓冲区,但是缓冲区中的数据还在,但是出于被遗忘状态。
byteBuffer.clear();
System.out.println("---------------clear-------------------");
System.out.println(byteBuffer.capacity());
System.out.println(byteBuffer.limit());
System.out.println(byteBuffer.position());
结果:
---------------clear-------------------
1024
1024
0
由结果可有看出 position 指向了0 ,limit指向了最末尾。这时可以继续/或者写。读的时候position会从0开始,没有数据的地方默认是0。写的时候position会从0开始,将会覆盖原来的值,然后filp()后继续读。
7,mark 标记。表示记录当前position的位置,在适当的时候调用reset() 让position恢复到 mark标记的位置
//记录当前位置
byteBuffer.mark();
//让position 恢复到 mark记录的位置
byteBuffer.reset();