从结构来看 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 1 2 3 4
图解:
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 1 2 3 4
可以看到 下标从 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 1 2 3 4
图解:
由图可知,当切换到读取模式后,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 1 2 3 4 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 1 2 3 4
由打印的结果可以看出,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 1 2 3 4
由结果可有看出 position 指向了0 ,limit指向了最末尾。这时可以继续/或者写。读的时候position会从0开始,没有数据的地方默认是0。写的时候position会从0开始,将会覆盖原来的值,然后filp()后继续读。
7,mark 标记。表示记录当前position的位置,在适当的时候调用reset() 让position恢复到 mark标记的位置
//记录当前位置 byteBuffer.mark(); //让position 恢复到 mark记录的位置 byteBuffer.reset();