简介
java nio 是jdk1.4引入的,其中包含 selector,channel,buffer 其中buffer是用来提高效率的。nio中操作数据,都是直接操作buffer对象\
buffer的类型
- ByteBuffer
- CharBuffer
- ShortBuffer
- IntBuffer
- LongBuffer
- FloatBuffer
- DoubleBuffer
java基本类型除了boolean外都有对应的buffer的对象,都是使用allocate()方法创建对应的buffer对象
Buffer 的相关属性
- capacity 容量
用来定义buffer的容量,在buffer初始化的时候设置,不可被修改 - limit 界限
- buffer的上限位置,limit <= capacity
- pasition 位置
- 读写buffer的时候,下一个写或者读的位置 pasition小于 limit
- mark 标记位置
- 使用mark()方法标记的位置,当调用reset()方法时,将pasition指向mark的位置
buffer 初始化
buffer 初始化调用 allocate()方法创建,下面看一下源码
1 | public static ByteBuffer allocate(int capacity) { |
可以看到 使用 new HeapByteBuffer(capacity, capacity); 在jvm堆中创建一个buffer对象
1 | Buffer(int mark, int pos, int lim, int cap) { |
当初始化Bytebuffer后实际的buffer对象的相关属性情况如下。
Buffer的核心方法
get()
1
2
3
4
5
6
7
8
9public byte get() {
return hb[ix(nextGetIndex())];
}
final int nextGetIndex() {
if (position >= limit)
throw new BufferUnderflowException();
return position++;
}put()
1
2
3
4
5
6
7
8
9
10public ByteBuffer put(byte x) {
hb[ix(nextPutIndex())] = x;
return this;
}
final int nextPutIndex() {
if (position >= limit)
throw new BufferOverflowException();
return position++;
}\
旧站配图 2 未恢复 · 原 OSS 存储桶已经删除,原始地址已记录在迁移清单中。
每次put的时候position 都指向后一位flip()
上图我们将a,b,c,d 加入到buffer后。当我们调用get()方法的时候是获取不到数据的,因为position是5调用get方法获取不到数据。
所以我们想获取数据,需要将position重新设置为0
查看get()源码,我们发现position >= limit才会抛出异常。所以我们还需要设置limit到5,需要两部操作。而flip()方法是将上面两个操作和成一个方法。执行的结果如下\旧站配图 3 未恢复 · 原 OSS 存储桶已经删除,原始地址已记录在迁移清单中。 Rewind()
我们指向将position恢复到0,不影响limit,可以调用这个方法。Clear()
调用clear方法,会将position设置到0,limit设置到capatity
在数组中真是的数据是没有被删除的。后续的put操作会覆盖原来的数据。Mark()
标记,表示记录到当前position 的位置可以通过reset()恢复到mark()标记位置hasremaining()
判断缓冲区中是否还有剩余数据Remaining()
获取缓冲区还可以操作的数据