Java语言进阶:Buffer类(缓冲区)
Buffer类(缓冲区)
概述:Buffer是一个抽象类,它是对某种基本类型的数组进行了封装。
作用: 在NIO中,就是通过 Buffer 来读写数据的。所有的数据都是用Buffer来处理的,它是NIO读写数据的中转池, 通常使用字节数组。
Buffer主要有如下几种:
- ByteBuffer
- CharBuffer
- DoubleBuffer
- FloatBuffer
- IntBuffer
- LongBuffer
- ShortBuffer
创建ByteBuffer
路径
- 创建ByteBuffer对象的三种方式
讲解
- ByteBuffer类内部封装了一个byte[]数组,并可以通过一些方法对这个数组进行操作。
- 创建ByteBuffer对象
- 方式一:在堆中创建缓冲区:allocate(int capacity)
public static void main(String[] args) {
//创建堆缓冲区
ByteBuffer byteBuffer = ByteBuffer.allocate(10);
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XmnmM9iK-1653718194143)(img/17.png)]
- 方式二: 在系统内存创建缓冲区:allocatDirect(int capacity)
public static void main(String[] args) {
//创建直接缓冲区
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(10);
}
- 在堆中创建缓冲区称为:间接缓冲区
- 在系统内存创建缓冲区称为:直接缓冲区
- 间接缓冲区的创建和销毁效率要高于直接缓冲区
- 间接缓冲区的工作效率要低于直接缓冲区
- 方式三:通过数组创建缓冲区:wrap(byte[] arr)
public static void main(String[] args) {
byte[] byteArray = new byte[10];
ByteBuffer byteBuffer = ByteBuffer.wrap(byteArray);
}
- 此种方式创建的缓冲区为:间接缓冲区
添加数据-put
讲解
- public ByteBuffer put(byte b):向当前可用位置添加数据。
- public ByteBuffer put(byte[] byteArray):向当前可用位置添加一个byte[]数组
- public ByteBuffer put(byte[] byteArray,int offset,int len):添加一个byte[]数组的一部分
public static void main(String[] args) {
yteBuffer b1 = ByteBuffer.allocate(10);
// 添加数据
b1.put((byte)11);
b1.put((byte)12);
b1.put((byte)13);
// ByteBuffer转换为普通字节数组
byte[] bytes = b1.array();
System.out.println(Arrays.toString(bytes));
// 打印结果: [11, 12, 13, 0, 0, 0, 0, 0, 0, 0]
}
public class Test_添加数据 {
public static void main(String[] args) {
ByteBuffer b1 = ByteBuffer.allocate(10);
// 添加数据
b1.put((byte)11);
b1.put((byte)12);
b1.put((byte)13);
// ByteBuffer转换为普通字节数组
byte[] bytes = b1.array();
System.out.println(Arrays.toString(bytes));
//打印结果: [11, 12, 13, 0, 0, 0, 0, 0, 0, 0]
System.out.println("=======================");
byte[] b2 = {14,15,16};
// 添加数据
b1.put(b2);
// ByteBuffer转换为普通字节数组
byte[] b = b1.array();
System.out.println(Arrays.toString(b));
//打印结果: [11, 12, 13, 14, 15, 16, 0, 0, 0, 0]
}
}
public class Test_添加数据 {
public static void main(String[] args) {
ByteBuffer b1 = ByteBuffer.allocate(10);
// 添加数据
b1.put((byte)11);
b1.put((byte)12);
b1.put((byte)13);
// ByteBuffer转换为普通字节数组
byte[] bytes = b1.array();
System.out.println(Arrays.toString(bytes));
// 打印结果: [11, 12, 13, 0, 0, 0, 0, 0, 0, 0]
System.out.println("=======================");
byte[] b2 = {14,15,16};
// 添加数据
b1.put(b2,0,1);
// ByteBuffer转换为普通字节数组
byte[] b = b1.array();
System.out.println(Arrays.toString(b));
// 打印结果: [11, 12, 13, 14, 0, 0, 0, 0, 0, 0]
}
}
容量-capacity
讲解
- Buffer的容量(capacity)是指:Buffer所能够包含的元素的最大数量。定义了Buffer后,容量是不可变的。
- 示例代码:
public static void main(String[] args) {
ByteBuffer b1 = ByteBuffer.allocate(10);
System.out.println("容量:" + b1.capacity());//10。之后不可改变
byte[] byteArray = {97, 98, 99, 100};
ByteBuffer b2 = ByteBuffer.wrap(byteArray);
System.out.println("容量:" + b2.capacity());//4。之后不可改变
}
- 结果:
容量:10
容量:4
限制-limit
讲解
- 限制limit是指:第一个不应该读取或写入元素的index索引。缓冲区的限制(limit)不能为负,并且不能大于容量。
- 有两个相关方法:
- public int limit():获取此缓冲区的限制。
- public Buffer limit(int newLimit):设置此缓冲区的限制。
- 示例代码:
public class Test_添加数据 {
public static void main(String[] args) {
ByteBuffer b1 = ByteBuffer.allocate(10);
// 添加数据
b1.put((byte)10);
// 获取限制
int limit1 = b1.limit();
System.out.println("limit1:"+limit1);// 10
// 设置限制
b1.limit(3);
// 添加元素
b1.put((byte)20);
b1.put((byte)30);
// b1.put((byte)40);// 报异常,因为限制位置索引为3,所以再存14就会报异常:BufferOverflowException
}
}
位置-position
讲解
- 位置position是指:当前可写入的索引。位置不能小于0,并且不能大于"限制"。
- 有两个相关方法:
- public int position():获取当前可写入位置索引。
- public Buffer position(int p):更改当前可写入位置索引。
- 示例代码:
public class Test_添加数据 {
public static void main(String[] args) {
ByteBuffer b1 = ByteBuffer.allocate(10);
// 添加数据
b1.put((byte)11);
// 获取当前位置索引
int position = b1.position();
System.out.println("position:"+position);// 1
// 设置当前位置索引
b1.position(5);
b1.put((byte)22);
b1.put((byte)33);
System.out.println("position:"+b1.position());// 7
System.out.println(Arrays.toString(b1.array()));
// 打印结果:[11, 0, 0, 0, 0, 22, 33, 0, 0, 0]
}
}
小结
注意: 字节缓冲数组能操作的范围就是position位置到limit位置:[position,limit)
标记-mark
讲解
- 标记mark是指:当调用缓冲区的reset()方法时,会将缓冲区的position位置重置为该索引。
- 相关方法:
- public Buffer mark():设置此缓冲区的标记为当前的position位置。
- public Buffer reset() : 将此缓冲区的位置重置为以前标记的位置。
- 示例代码:
public static void main(String[] args) {
ByteBuffer b1 = ByteBuffer.allocate(10);
// 添加数据
b1.put((byte)11);
// 获取当前位置索引
int position = b1.position();
System.out.println("position:"+position);// 1
// 标记当前位置索引
b1.mark();
// 添加元素
b1.put((byte)22);
b1.put((byte)33);
// 获取当前位置索引
System.out.println("position:"+b1.position());// 3
System.out.println(Arrays.toString(b1.array()));
// 打印结果:[11, 22, 33, 0, 0, 0, 0, 0, 0, 0]
// 重置当前位置索引
b1.reset();
// 获取当前位置索引
System.out.println("position:"+b1.position());// 1
// 添加元素
b1.put((byte)44);
System.out.println(Arrays.toString(b1.array()));
// 打印结果:[11, 44, 33, 0, 0, 0, 0, 0, 0, 0]
}
其它方法
讲解
- public int remaining():获取position与limit之间的元素数。
- public boolean isReadOnly():获取当前缓冲区是否只读。
- public boolean isDirect():获取当前缓冲区是否为直接缓冲区。
- public Buffer rewind():重绕此缓冲区。
- 将position位置设置为:0
- 限制limit不变。
- 丢弃标记。
- public Buffer clear():还原缓冲区的状态。
- 将position设置为:0
- 将限制limit设置为容量capacity;
- 丢弃标记mark。
- public Buffer flip():缩小limit的范围。
- 将limit设置为当前position位置;
- 将当前position位置设置为0;
- 丢弃标记。
package com.itheima.demo11_ByteBuffer常用方法;
import java.nio.ByteBuffer;
import java.util.Arrays;
/**
* @Author:pengzhilin
* @Date: 2020/9/23 15:33
*/
public class Test6_clear和flip {
public static void main(String[] args) {
/*
- public Buffer clear():还原缓冲区的状态。
- 将限制limit设置为容量capacity;
- 将position设置为:0
- 丢弃标记mark。
- public Buffer flip():缩小limit的范围。
- 将limit设置为当前position位置;
- 将当前position位置设置为0;
- 丢弃标记。
*/
// 创建ByteBuffer字节缓冲数组
ByteBuffer b = ByteBuffer.allocate(10);
// 容量:10,限制:10,位置:0
System.out.println("容量:" + b.capacity() + ",限制:" + b.limit() + ",位置:" + b.position());
// 往b添加数据
b.put((byte) 10);
b.put((byte) 20);
b.put((byte) 30);
// 容量:10,限制:10,位置:3
System.out.println("容量:" + b.capacity() + ",限制:" + b.limit() + ",位置:" + b.position());
System.out.println(Arrays.toString(b.array()));// [10, 20, 30, 0, 0, 0, 0, 0, 0, 0]
/*// 调用clear
b.clear();
// 容量:10,限制:10,位置:0
System.out.println("容量:"+b.capacity()+",限制:"+b.limit()+",位置:"+b.position());
System.out.println(Arrays.toString(b.array()));// [10, 20, 30, 0, 0, 0, 0, 0, 0, 0]
*/
// 调用flip()
b.flip();
// 容量:10,限制:3,位置:0
System.out.println("容量:"+b.capacity()+",限制:"+b.limit()+",位置:"+b.position());
System.out.println(Arrays.toString(b.array()));// [10, 20, 30, 0, 0, 0, 0, 0, 0, 0]
}
}
笔记如有错误之处,请各位大佬指正,欢迎评论留言,不胜感激!!!