*Buffer : 缓冲区 是特定基本类型元素的线性有限序列
Buffer中的数据结构是原始数据类型的数组
例如 jdk ByteBuffer中定义的byrte数组
public abstract class ByteBuffer extends Buffer
implements Comparable<ByteBuffer>
{
final byte[] hb;
}
Buffer类图(除去boolean原始类型没有 其他都有)
*Buffer的实例化
1.Buffer具体子类的allocate方法
例如 ByteBuffer
public static ByteBuffer allocate(int capacity){} //参数为Buffer的容量
2.Buffer具体子类的wrapa方法
例如DoubleBuffer
public static DoubleBuffer wrap(double[] array) {}
*重要属性(父类Buffer中定义):
1.capacity 容量 缓冲区中能够容纳元素的数量 也就是Buffer中数组的大小 不可以改变
2.position 位置 下一个要操作(读写)的元素索引 位置会随着调用相应的read put等方法改变
3.limit 上限 缓冲区中目前容纳了 多少元素 也就是缓冲区中目前元素的个数
4.mark 用于记录position的当前位置 在调用reset方法 重新设置position的值为 mark变量上次记录的
上面四个属性 要遵循一下关系
0 <= 标记(mark) <= 位置(position) <= 限制 (limit)<= 容量(capacity)
* 重要方法(以ByteBuffer为例)
1. 获取缓冲区中的内容 此方法有多个版本重载
public byte get() {
return hb[ix(nextGetIndex())];
}
2.向缓冲区写入数据 有多个重载
public ByteBuffer put(byte x) {
hb[ix(nextPutIndex())] = x;
return this;
}
3.在当前缓冲区基础上 创建一个新的缓冲区
public ByteBuffer slice() {
return new HeapByteBuffer(hb, -1, 0,this.remaining(),this.remaining(), this.position() + offset);
}
4 返回缓冲区的容量
public final int capacity() {
return capacity;
}
5. 为position做个标记
public final Buffer mark() {
mark = position;
return this;
}
6.将缓冲区的位置设置为以前标记的位置
public final Buffer reset() {
int m = mark;
position = m;
return this;
}
7.返回缓冲区下一个要操作元素的索引
public final int position() {
return position;
}
8.设置缓冲区起始操作(读写)索引 和 有效数据索引
public final Buffer flip() {
limit = position;
position = 0;
mark = -1;
return this;
}
9.重置缓冲区
public final Buffer clear() {
position = 0;
limit = capacity;
mark = -1;
return this;
}
后面两个方法很重要
读文件的实例代码
//..省略
FileChannel fileChannel = fileInputStream.getChannel();
//1.初始化内部数组
ByteBuffer buffer = ByteBuffer.allocate(4);
//2.read方法会设置position
while(fileChannel.read(buffer) != -1) {
//3.limit = position;
//position = 0
buffer.flip();
System.out.println(charset.decode(buffer));
//4.position = 0, limit=capacity
buffer.clear();
}
//..省略
1.初始化容量为 4的Buffer Buffer 数组全部是空的
2.调用Channel的read方法 向缓冲区写入2个字节
3.如果这个时候调用 Buffer get方法 读的是position =2 limit=3之间的数据
4.调用 Buffer #flip方法之后
5.再一次调用Buffer get方法
6.Buffer clean方法