Buffer表示缓冲区,用于nio中输入和输出存放和读取数据,他是一个数组,创建后就不能改变大小.
原来java.io的流操作在nio中就是对buffer操作.
*4个内部索引
---capacity,buffer的容量
int capacity()
---position,下一个要读/写的元素(从0开始),>=0 && <=limit
int position() //回去当前position
Buffer position(int newPosition) //改变position的值,返回自身
---limit,第一个不可读/写元素,<=capacity
int limit()
Buffer limit(int newlimit)
---mark,作用是记录position,以便回退
final Buffer mark() { mark = position; //记录当前位置 return this; }
final Buffer reset() { int m = mark; if (m < 0) throw new InvalidMarkException(); position = m; //将mark设置为position return this; }
---确定关系
0<=mark<=position<=limit<=capacity
---剩余字节数
boolean hasRemaining()
int remaining()
*创建buffer的4个静态方法
---ByteBuffer allocateDirect(int capacity)
这是ByteBuffer唯有的特性,使用系统能直接操作IO的存储空间作为缓存区,这样免去了java的buffer和系统buffer之间的数据复制.
注意,
1.DirectBuffer没有后援数组,故调用array(),arrayOffset()会抛异常.
2.系统或JVM不一定支持DirectBuffer
3.创建和销毁DirectBuffer,消耗更多的系统资源,故适合大量和长时间的IO需求
---ByteBuffer allocate(int capacity)
---ByteBuffer wrap(byte[] array)
创建指向array的引用,array被称为后援数组.
---ByteBuffer wrap(byte[] array, int offset, int length)
*Buffer操作
---clear()
position=0,limit =capacity
---flip(),写入数据前
limit=position,position=0
---rewind(),重新读取
limit不变,position=0
---compact()
将position和limit之间的数据复制到开始处.注,复制数据非常消耗系统资源.
//HeapByteBuffer.compact()实现代码 public ByteBuffer compact() { System.arraycopy(hb, ix(position()), hb, ix(0), remaining()); position(remaining()); limit(capacity()); return this; } /* * ByteBuffer.compact()注释中对compact的典型案例 * buf.clear(); // Prepare buffer for use * while (in.read(buf) >= 0 || buf.position != 0) { * buf.flip(); * out.write(buf); * buf.compact(); // In case of partial write * } */
*buffer透视api,
含义:与原buffer共享一个后援数组,状态变量独立.见另一文章buffer view
---duplicate()
public ByteBuffer duplicate() { return new HeapByteBuffer(hb, //共享同一个数组 this.markValue(), //状态信息初始为this的值 this.position(), this.limit(), this.capacity(), offset); }
---slice(),将当前position到limit之间的空间作为新buffer的操作区域,一个切片操作
public ByteBuffer slice() { return new HeapByteBuffer(hb, //共享同一数组,array()返回同一值 -1,u 0, this.remaining(), this.remaining(), this.position() + offset); //offset从当前position开始 }
与duplicate()功能相同,只是isReadOnly=true;
*总结
---buffer通过对外提供抽象方法,对内通过具体实现类实现的API设计方式,简洁安全的设计风格
---链式设计,代码简洁
---状态变量的设计,有创意
---慎用DirectBuffer和compact.