一、buffer
缓冲区即在内存中开辟的一段连续的存储空间,用于临时存放数据
1.基本概念
capacity:容量,一旦创建,不可修改
limit:限制位;
position:位置符号
写操作:limit = capacity ; position = {0,capacity-1} 即 positon < limit
读操作:limit = position (停止写入数据时的position位置,表示当前可读取的内容的最大长度),position = 0 (从缓冲区开始位置读取内容)
mark:标记位,默认值-1
2.创建
// 1.创建空缓冲区,设置容量大小,单位字节,如:1024B = 1KB ByteBuffer byteBuffer = ByteBuffer.allocate(1024); // 2.根据已有内容,创建缓冲区 // capacity = byte[].length // position = 0 // mark = -1 // limit = position + length = capacity ByteBuffer byteBuffer1 = ByteBuffer.wrap("abc".getBytes());
3.写入
// capacity = 1024 // position = 3 ,写入数据时position从0开始,写入一个,position下移一位 // mark = -1 // limit = 1024 byteBuffer.put("abc".getBytes());
若此时读取数据
System.out.println("try to get from buffer"); System.out.println(byteBuffer.get());
结果:0
原因在于读取数据时根据读取positon位置处的值,此时position=3指向一个未写入数据的位置,0为默认值
4.写转读
// 1.变更 limit ,limit的值为当前允许读取的最大长度位置即写入数据 // limit = position 当前的position位置 // 2.变更 position ,读取数据应从 position = 0 从头读取 // byteBuffer.limit(byteBuffer.position()); // byteBuffer.position(0); byteBuffer.flip();
5.读取
// 已写入数据的个数 // byteBuffer.limit() - byteBuffer.position(); // byteBuffer.remaining() > 0; // byteBuffer.hasRemaining() ==》 limit - position while(byteBuffer.hasRemaining()){ byte b = byteBuffer.get(); System.out.println((char)b); }
6.清空
读取数据后,清空已有数据,重新写入
// clear 清空缓冲区,实质,缓冲区中的内容并未被清空,只是做了一些看似清空缓冲区的操作 // 将 position = 0 ,limit = capacity 即 相当于初始化了缓冲区 // 即,所谓的清空缓冲区,是靠重新写入的数据覆盖完成的 // 又因为 position < limit ,所以在覆盖的情况下也只能读取到覆盖后的内容,读取不到未覆盖的内容 // 故感觉上是缓冲区清空了 byteBuffer.clear(); // 1.初始化时,写入"abc" 三个字符,现写入"xy"两个字符,强制获取第2(因为position是从0开始计数)个位置的数据 // 2.获取到的数据内容为 c ,说明,clear 并未清空缓冲区 byteBuffer.put("xy".getBytes()); byte result = byteBuffer.get(2); System.out.println((char)result);
7.标记
byteBuffer.put("def".getBytes()); byteBuffer.flip(); // 此时缓冲区里面的内容为:"xydef" System.out.println((char)byteBuffer.get()); // 在第二个字符处,即position=1的位置做标记,mark = 1 byteBuffer.mark(); System.out.println("======get======"); while(byteBuffer.hasRemaining()){ System.out.println((char)byteBuffer.get()); } System.out.println("======reset======"); // 重置 position = mark byteBuffer.reset(); while(byteBuffer.hasRemaining()){ System.out.println((char)byteBuffer.get()); }
8.重读
// 重新读取数据 // position = 0 , mark = -1 byteBuffer.rewind(); while(byteBuffer.hasRemaining()){ System.out.println((char)byteBuffer.get()); }
9.清空已读内容,保留未读内容
// compact 将未读取内容,重置到缓冲区起始位置,再次写入内容时从未读数据的最后一个位置开始写入 byteBuffer.rewind(); for(int i = 0 ; i < 2 ; i ++){ System.out.println((char)byteBuffer.get()); } byteBuffer.compact(); byteBuffer.put("hij".getBytes()); byteBuffer.rewind(); System.out.println("compact"); while(byteBuffer.hasRemaining()){ System.out.println((char)byteBuffer.get()); } // 输出 defhij