/** * 缓冲区(Buffer):在java NIO 中负责存储数据;缓冲区就是数组,存储不同类型的数据; * * 根据不同的类型(boolean类型除外),提供了相应类型的缓冲区; * ByteBuffer * CharBuffer * ShortBuffer * IntBuffer * LongBuffer * FloatBuffer * DoubleBuffer * * 上述缓冲区的管理方式几乎一致,都是使用 allocate();获取缓冲区 * * 缓冲区中存储数据的核心 * put();存入数据到缓存区中 * get();获取缓冲区中的数据 * * 缓冲区的四大核心属性: * capacity:容量、表示缓冲区中最大存储数据的容量、一旦声明不能更改; * limit:界限、表示缓冲区中可以操作数据的大小;(limit 后数据不能进行读写); * position:位置、表示缓冲区中正在操作数据的位置; * * mark:标记、表示记录当前 position 的位置;可以通过 reset() 将恢复 position 到 mark记录的位置; * * mark <= position <= limit <= capacity */ public class TestBuffer { public static void main(String[] args) { test01(); } public static void test01(){ //一个大小为 5 个字节的字符串 String str = "abcde"; //1、分配一个指定大小的缓冲区 ByteBuffer byteBuffer = ByteBuffer.allocate(1024); System.out.println("--------allocate()--------"); //查看当前缓冲区、正在操作数据的位置(当前缓冲区未写入数据、因此 position指向第一个位置、也就是起始位置、下标为 0) System.out.println(byteBuffer.position()); //查看当前缓冲区、可操作数据最大位置(当前是写入模式、最多可以写入 1024 字节) System.out.println(byteBuffer.limit()); //查看当前缓冲区、容量(当前缓冲区容量为 1024 字节) System.out.println(byteBuffer.capacity()); //2、利用 put() 将数据存入到缓冲区 System.out.println("---------put()------------"); //将字符串转换为字节并存储到缓冲区 byteBuffer.put(str.getBytes()); //当前缓冲区存入了5个字节、下标 0-4、因此 position 指向下标为 5; System.out.println(byteBuffer.position()); //当前缓冲区可存入的最大位置为 1024 System.out.println(byteBuffer.limit()); //当前缓冲区的容量是 1024 System.out.println(byteBuffer.capacity()); //3、切换到读取数据的模式 System.out.println("---------flip()------------"); byteBuffer.flip(); //当前是读取数据模式、当前 position在起始位置、下标为 0 System.out.println(byteBuffer.position()); //当前缓冲区存入了 5字节、下标 0-4、limit指向 下标 5(表示当前缓冲区最多可操作 5个字节、下标0-4) System.out.println(byteBuffer.limit()); //当前缓冲区容量为 1024 System.out.println(byteBuffer.capacity()); //4、利用 get() 读取缓冲区中的数据 System.out.println("---------get()------------"); //创建一个字节数组、5 个长度 byte[] bytes = new byte[byteBuffer.limit()]; //获取缓冲区的所有数据、并存入到字节数组中 byteBuffer.get(bytes); //创建一个字符串(当前字节数组从 下标 0开始、5个长度)并输出 System.out.println(new String(bytes,0,bytes.length)); //当前取出了所以数据、下标 0-4、因此 position指向 5 System.out.println(byteBuffer.position()); //当前可操作的数据是 5个长度 System.out.println(byteBuffer.limit()); //容量 1024 System.out.println(byteBuffer.capacity()); //5、利用 rewind() 可重复读取缓冲区中的数据 System.out.println("---------rewind()------------"); //将当前缓冲区的 position 置为起始位置处 下标 0 //并且将 mark 置为默认值 -1 byteBuffer.rewind(); //0 System.out.println(byteBuffer.position()); //5 System.out.println(byteBuffer.limit()); //1024 System.out.println(byteBuffer.capacity()); System.out.println("---------mark()------------"); //6、利用 mark()记录当前 position的位置 byte[] byteArr = new byte[10]; //从 byteBuffer缓冲区中取出 2个元素、下标 从 0开始 即 0、1 byteBuffer.get(byteArr,0,2); //输出 System.out.println(new String(byteArr,0,10)); //当前 position下标 指向 2 System.out.println(byteBuffer.position()); //当前 limit下标 指向 5 System.out.println(byteBuffer.limit()); //容量 1024 System.out.println(byteBuffer.capacity()); //使用 mark()记录当前 position byteBuffer.mark(); //当前从缓冲区再取出一个字节、若当前 position指向 limit(最大可操作数量)、再次取出数据时会抛出异常 byteBuffer.get(); //当前 position下标 指向 3 System.out.println(byteBuffer.position()); //当前 limit下标 指向 5 System.out.println(byteBuffer.limit()); //容量 1024 System.out.println(byteBuffer.capacity()); //使用reset()复原 position、基于 mark的记录、如果 mark 为默认值 -1、则会抛出异常 byteBuffer.reset(); //当前 position下标 指向 2 System.out.println(byteBuffer.position()); //当前 limit下标 指向 5 System.out.println(byteBuffer.limit()); //容量 1024 System.out.println(byteBuffer.capacity()); System.out.println("----------------------"); //判断缓冲区是否还有剩余数据 if (byteBuffer.hasRemaining()){ //返回缓冲区剩余数据的数量 System.out.println(byteBuffer.remaining()); } //10、利用 clear() 清空缓冲区、缓冲区中的数据依然存在、处于一个 ”被遗忘“的状态; System.out.println("---------clear()------------"); //将 position 置为起始位置处 下标 0 //将 limit 置为 容量值 capacity //并且将 mark 置为默认值 -1 byteBuffer.clear(); System.out.println(byteBuffer.position()); System.out.println(byteBuffer.limit()); System.out.println(byteBuffer.capacity()); } }
非直接缓冲区:通过 allocate(int size);分配的缓冲区、将缓冲区建立在 JVM 内存中;
直接缓冲区:通过 allocateDirect(int size);分配的缓冲区、将缓冲区建立在操作系统的物理内存之中;可以提高效率
public static void test02(){ //创建一个非直接缓冲区 ByteBuffer byteBuffer = ByteBuffer.allocate(1024); //byteBuffer.isDirect() 返回true:直接缓冲区、false:非直接缓冲区 System.out.println(byteBuffer.isDirect());//false ByteBuffer byteBuffer2 = ByteBuffer.allocateDirect(1024); System.out.println(byteBuffer2.isDirect());//true }
原文:https://www.cnblogs.com/jhdhl/p/14784750.html