1.基础
缓冲区是包在一个对象内的基本数据元素数组。
1.1 关键词
容量(Capacity)
缓冲区能够容纳的数据元素的最大数量。这一容量在缓冲区创建时被设定,并且永远不能 被改变。
上界(Limit)
缓冲区的第一个不能被读或写的元素。或者说,缓冲区中现存元素的计数。
位置(Position)
下一个要被读或写的元素的索引。位置会自动由相应的 get( )和 put( )函数更新。
标记(Mark)
一个备忘位置。调用mark( )来设定mark=postion。调用reset( )设定position= mark。标记在设定前是未定义的(undefined)。
- 新建的buffer(容量为10)
位置被设为 0,mark 为空,而且容量和上界被设为 10,刚好经过缓冲区能够容纳的最后一个字节。 标记最初未定义。容量是固定的,但另外的三个属性可以在使用缓冲区时改变。
1.2 通用API
package java.nio;
public abstract class Buffer {
public final int capacity( )
public final int position( )
public final Buffer position (int newPositio public final int limit( )
public final Buffer limit (int newLimit) public final Buffer mark( )
public final Buffer reset( )
public final Buffer clear( )
public final Buffer flip( )
public final Buffer rewind( )
public final int remaining( )
public final boolean hasRemaining( ) public abstract boolean isReadOnly( );
}
1.3 数据存取
通常来讲,buffer通过get来读取数据,通过put来写入数据。但是无论使用put还是get操作,都会使position增加。所以buffer在不进行flip操作的情况下,不能又读又存。此外,如果使用类似:public abstract ByteBuffer put (int index, byte b)
和public abstract byte get (int index)
这样带位置参数的方法存取数据将不会修改position
属性。
例如:
- 开始时,position = 5
- 调用
buffer.put(0,(byte)'M').put((byte)'w')
后,position = 6.说明put(0,(byte)‘M’)并没有改变position的位置。
1.4 flip()
操作
该操作的作用是将buffer有填充状态变为待读取状态
通道从buffer中读取数据需要知道数据的起止点和终点。需要通过flip()
方法,将limit
指向position
,同时将position
指向0
1.5 hasRemaining()
操作
该操作的作用是释放缓冲区时告诉您是否已经达到缓冲区的上界。
// 示例1
for (int i = 0; buffer.hasRemaining( ), i++) {
myByteArray [i] = buffer.get( );
}
// 示例2
int count = buffer.remaining( );
for (int i = 0; i < count, i++) {
myByteArray [i] = buffer.get( );
}
1.6 conpat()
压缩操作
将从position位置开始往后的数据往前覆盖。position会移到末尾。他的作用是移除已经使用的数据
当使用compact
之后,如果继续使用put的操作,会覆盖position之后的数据。
1.7 缓存区比较
equals
- buffer的类型要相同,例如都是byteBuffer
- limit 到capacity的距离要相同
- 从position到limit之间的序列要相同
2. 缓冲区创建
// 示例1
ByteBuffer byteBuffer0 = ByteBuffer.allocate(10);
// 示例2
byte[] bytes = new byte[1024];
ByteBuffer byteBuffer1 = ByteBuffer.wrap(bytes);
// its position will be offset,its limit will be offset + length
ByteBuffer byteBuffer2 = ByteBuffer.wrap(bytes, 0, 1);
3. 直接缓冲区和非直接缓冲区
直接缓冲区:将缓冲区建立在物理内存中
非直接缓冲区:将缓冲区建立在内存中