Buffer(缓冲区)本质上是一个由基本类型数组构成的容器。
我们先看看Buffer类的基本构成:
public abstract class Buffer { // Invariants: mark <= position <= limit <= capacity private int mark = -1; private int position = 0; private int limit; private int capacity; }
再看看子类ByteBuffer 的构成:
public abstract class ByteBuffer extends Buffer implements Comparable{ // These fields are declared here rather than in Heap-X-Buffer in order to // reduce the number of virtual method invocations needed to access these // values, which is especially costly when coding small buffers. // final byte[] hb; // Non-null only for heap buffers final int offset; boolean isReadOnly; }
因此一个ByteBuffer 对象由基本的五大属性组成:
核心属性:
● mark 初始值为-1,用以标记当前position的位置。对应方法为 mark()。
● position 初始值为0,读、写数据的起点位置。对应方法为 position()。
● limit 界限,和position 组成可读、可写的数据操作区间。对应方法为 limit()。
● capacity 缓冲区的大小。对应方法为capacity()。
数据存储:
● hb 一个基本类型构成的数据,大小等于capacity。
核心方法:
● put() 写数据。
● get() 读数据。
● flip() 翻转。如当 put 完数据之后,调用flip s 是为了告知下次 get 数据需要读取数据区间。反过来也是一样的道理。
public final Buffer flip() { limit = position; position = 0; mark = -1; return this; }
● clear() 清空。不会清除数据,但会各个属性回归初始值。
public final Buffer clear() { position = 0; limit = capacity; mark = -1; return this; }
● rewind 倒带。当需要重读、重写的时候可以使用。
public final Buffer rewind() { position = 0; mark = -1; return this; }
● remaning() 返回剩余未被处理的数量。
public final int remaining() { return limit - position; }
假设我们声明了一个 capacity 为 5 的字节缓冲区:
ByteBuffer buf = ByteBuffer.allocate(4);
那么,缓冲区的初始状态就是如下图所示ÿ