NIO - Buffer缓冲区
*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方法