Java - ByteBuffer字节数组缓冲器。读取数据和写入数据执行flip和clear的原理

ByteBuffer继承于Buffer。

使用一个字节数组作为缓冲器。读取的数据和发送的数据会放入字节数组hb中。当数组达到一定大小,一次性写入通道或者读取。避免每次操作都要进行读写操作。

public abstract class ByteBuffer extends Buffer implements Comparable
{
    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;
    }

 

你可能感兴趣的:(Java)