基本概念
1. Buffer是一个抽象类publicabstract class Buffer
2. 简而言之Buffer是一个指定的原始数据类型(data of a specific primitive type)容器
3. 一个buffer实例是一个线性,有序的特定原始数据类型的序列。除了内容之外,他还有三个必要的属性:capacity,limit以及position:
1) buffer的capacity是指它所能包含元素的数量。其capacity不能为负而且大小不会改变
2) buffer的limit是指第一个不能被读写元素的下标(index). limit不能为负数而且不能大于buffer的capacity
3) buffer的position是指下一个能被读或者写的元素的下标(index).position不能为负数而且不能大于limit
传输数据(Transferring data)
Buffer的每个子类都定义了两种类别的操作:get和put:
1. get和put操作都是从当前的position开始的,接着position也会递增对应的数量。如果 get 和put的操作超过了buffer的限制(limit),
相应的get操作会抛出 BufferUnderflowException,响应的put操作会抛出BufferOverflowException;这两种情况下都不会有数据会被传输。
2. 数据会被相应通道(channel)的I/O操作从buffer中转入转出,这个通道和当前position相关。
Marking and resetting(标记和重置)
当调用重置方法时,buffer的标记变为position的索引,即此时的mark为index。标记不一定要被buffer实例定义,被定义后他的值不能小于0
而且也不能大于position。如果buffer定义了mark,那么当程序运行至position和limit小于mark时,程序就会丢弃当前mark。如果mark没有被
定义那么当程序调用reset方法时就会引起InvalidMarkException异常。
Invarlants(不变式)
下面的不变式展现了mark,position,limit和capacity的关系:
0<=mark<=position<=limit<=capacity
一个新创建的buffer,position的值被初始化为0,标记也没有被定义。limit的值可能被初始化为0也有可能被初始化为其他值这取决于buffer的
类型 以及何种构造方式。新分配的缓冲区(buffer)的每个元素被初始化为零。
Clearing,flipping,and rewinding
除了访问position,limit,以及capacityvalues以及标记重置方法职位,此类还定义了下面这些buffer上的操作:
- clear() 让一个缓冲区准备好一个读通道(channel-red)的序列或者相对应的put操作:把limit的值设为缓冲区的容量以及把position设为0.
- flip() 让一个buffer准备好接受一个写通道(channel-write)序列或者相对应的get操作:这会把limit的值设为当前position的值随后会把position变为0
- rewind() 将数据回退,limit不变,把position设为0,即缓冲区的起始位置
Read-only buffers
每一个buffer都是可读的,但并不是每个buffer都是可写的。可读的缓冲区不允许他的内容被改变,但是他的mark,position,以及limit值可以改变。 判断一个buffer是否是只读的可以通过isReadOnly方法来判断.
Thread safety
Buffers在多线程环境下是线程不安全的。如果一个buffer在多线程环境下使用可以通过合适的同步方式来进行控制。
Invocation chaining(调用链)
此类中的方法一般会返回Buffer类型,除非特别指定返回其他类型。这种方式就允许方法可以以链接的方式调用;例如,下面的语句:
b.flip();
b.position(23);
b.limit(42);
可以被替换为下面一句:b.flip().position(23).limit(42);