ByteBuffer继承于Buffer。
使用一个字节数组作为缓冲器。读取的数据和发送的数据会放入字节数组hb中。当数组达到一定大小,一次性写入通道或者读取。避免每次操作都要进行读写操作。
public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer>
{
final byte[] hb; /** 非空数组,用于堆缓冲区*/
final int offset; /** 偏移量 */
boolean isReadOnly; /** 是否只读*/
...
}
为了方便管理该字节数组,使用了偏移量offset 以及Buffer类中的
private int mark = -1; // 标志,可用于恢复重做
private int position = 0; // 当前位置
private int limit; // 本次操作最大的字节大小
private int capacity; // 容量大小
long address; // 地址:仅由直接缓冲区使用。
具体原理是,将数据放入字节数组中,并用limit告知本数组中的有效数据大小。position为当前操作的下标。
mark是标志上一次执行完整读取或者存放一系列数据成功之后的下标(需要手动设置),如果本次操作发生错误,则只需要从mark下标处重新操作。不需要从下标0开始。
在准备从buffer中读取数据时,需要先执行flip()操作。设置关于读取数据的参数。将limit设为有效字符的大小,即上次操作之后的下标position。修改position为0,意为下次从0开始读取数据。mark设为初始值-1;
/** 用于读取前操作,设置读取的长度limit,下标归0*/
public final Buffer flip() {
limit = position;
position = 0;
mark = -1;
return this;
}
如果不执行flip操作,会导致从末尾进行读取操作,那得到的数据为0,或者为内存中残留数据。
与之相对应的,写数据进buff时。需要执行clear()操作。旨在修正各项下标参数为初始值,从0开始写入。
如果不执行clear()操作,直接执行read,那等同于追加操作。
public final Buffer clear() {
position = 0;
limit = capacity;
mark = -1;
return this;
}