Buffer是一个用于特定基本类型数据的容器, 是特定基本类型元素的线性有限序列,对于每个非 boolean 基本类型,此类都有一个子类与之对应。Buffer非线程安全。类图如下:
一、属性
- mark,用于标记一个位置,配合reset()使用,初始值-1,调用mark()后将值设置为当前position的值。
- position,下一个读或者写的位置。
- limit,第一个不能读取或写入元素的位置。
- capacity ,缓冲区的容量。
四者之间的关系:mark <= position <= limit <= capacity。
二、构造Buffer
Buffer有两种构造模式,分只读Buffer和可读写Buffer,只读Buffer从可读写Buffer上调用asReadOnlyBuffer方法得到。其一是非直接模式,在虚拟机堆上构建Buffer,具体实现类为HeapXXXBuffer、HeapXXXBufferR(只读Buffer),其内有一个基本类型的数组,以及一个偏移量offset,代表Buffer使用数组从offset位置开始,到数组结束位置的数据空间。
- 调用allocate创建,在堆上创建一个基本类型的数组来维护数据。
- 调用wrap创建,包装一个已有的基本类型数组来维护数据。
其二是直接模式,直接的操作系统内存中分配缓存,调用allocateDirect方法创建。建议将直接缓冲区主要分配给那些易受本机 I/O 操作影响的大型、持久的缓冲区。一般情况下,最好仅在直接缓冲区能在程序性能方面带来明显好处时分配它们。
三、API
- capacity,返回缓冲区容量。
- clear,清空缓存区,设置position = 0 limit = capacity mark = -1;
- flip,反转缓存区,切换到读模式,设置limit = position position = 0 mark = -1
- limit,返回缓冲区limit值。
- limit(int newLimit),设置limit值。
- mark,设置标志位,mark = position
- position,返回position的值。
- position(int newPosition),设置position的值。
- remaining,返回缓冲区剩余可用空间大小,返回值为limit - position。
- hasRemaining,返回是否还有可用空间,return position < limit。
- reset,将position重置到标志位mark,设置position = mark。
- rewind,重绕此缓冲区,设置 position = 0 mark = -1,调用此方法是在limit被设置为恰当值的前提下,通常用于重新读取已经被flip的buffer。
四、数据操作
-
读取数据:通过get(),get(index)。get()从position位置读取,position值加一;get(index)从index位置读取,不改变position。
-
写入数据: 通过put(byte),put(index,byte)。put(byte)写入position位置,position值加一;put(index,byte)写入index位置,不改变position。
-
批量读取数据:get(XXX[] dst),get(XXX[] dst, int offset, int length)。
- 批量写入数据:put(XXXBuffer src),put(XXX[] src, int offset, int length),put(byte[] src)