NIO - Buffer缓冲区

来源:互联网 发布:it serves you right 编辑:程序博客网 时间:2024/05/01 21:54

转自:http://blog.csdn.net/java2000_wl/article/details/7615543

*Buffer : 缓冲区  是特定基本类型元素的线性有限序列  

                 Buffer中的数据结构是原始数据类型的数组

例如   jdk  ByteBuffer中定义的byrte数组

[java] view plaincopyprint?
  1. public abstract class ByteBuffer  extends Buffer  
  2.     implements Comparable<ByteBuffer>  
  3. {  
  4.     final byte[] hb;  
  5. }  

Buffer类图(除去boolean原始类型没有  其他都有)


*Buffer的实例化

1.Buffer具体子类的allocate方法

  例如 ByteBuffer 

[java] view plaincopyprint?
  1. public static ByteBuffer allocate(int capacity){}  //参数为Buffer的容量  

2.Buffer具体子类的wrapa方法

 例如DoubleBuffer

[java] view plaincopyprint?
  1. public static DoubleBuffer wrap(double[] array) {}  


*重要属性(父类Buffer中定义):

1.capacity  容量  缓冲区中能够容纳元素的数量  也就是Buffer中数组的大小   不可以改变

2.position  位置  下一个要操作(读写)的元素索引  位置会随着调用相应的read  put等方法改变

3.limit     上限   缓冲区中目前容纳了 多少元素  也就是缓冲区中目前元素的个数

4.mark    用于记录position的当前位置  在调用reset方法  重新设置position的值为 mark变量上次记录的

 上面四个属性 要遵循一下关系

  0 <= 标记(mark) <= 位置(position) <= 限制 (limit)<= 容量(capacity)

* 重要方法(以ByteBuffer为例)

 1. 获取缓冲区中的内容 此方法有多个版本重载

[java] view plaincopyprint?
  1. public byte get() {  
  2. urn hb[ix(nextGetIndex())];  
  3. }  

2.向缓冲区写入数据  有多个重载

[java] view plaincopyprint?
  1.   public ByteBuffer put(byte x) {  
  2. hb[ix(nextPutIndex())] = x;  
  3. return this;  
  4.    }  

3.在当前缓冲区基础上  创建一个新的缓冲区

[java] view plaincopyprint?
  1. public ByteBuffer slice() {  
  2. urn new HeapByteBuffer(hb, -10,this.remaining(),this.remaining(), this.position() + offset);  
  3. }  

 4 返回缓冲区的容量

[java] view plaincopyprint?
  1. public final int capacity() {  
  2. urn capacity;  
  3. }  

  5. 为position做个标记

[java] view plaincopyprint?
  1.    public final Buffer mark() {  
  2. mark = position;  
  3. return this;  
  4.    }  

  6.将缓冲区的位置设置为以前标记的位置

[java] view plaincopyprint?
  1.    public final Buffer reset() {  
  2.        int m = mark;  
  3. position = m;  
  4. return this;  
  5.    }  

  7.返回缓冲区下一个要操作元素的索引

[java] view plaincopyprint?
  1. public final int position() {  
  2. urn position;  
  3. }  

  8.设置缓冲区起始操作(读写)索引 和  有效数据索引

[java] view plaincopyprint?
  1.    public final Buffer flip() {  
  2. limit = position;  
  3. position = 0;  
  4. mark = -1;  
  5. return this;  
  6.    }  

   9.重置缓冲区

[java] view plaincopyprint?
  1.    public final Buffer clear() {  
  2. position = 0;  
  3. limit = capacity;  
  4. mark = -1;  
  5. return this;  
  6.    }  

    后面两个方法很重要  

     读文件的实例代码

[java] view plaincopyprint?
  1. //..省略  
  2.         FileChannel fileChannel = fileInputStream.getChannel();  
  3.         //1.初始化内部数组  
  4.         ByteBuffer buffer = ByteBuffer.allocate(4);  
  5.         //2.read方法会设置position  
  6.         while(fileChannel.read(buffer) != -1) {  
  7.             //3.limit = position;   
  8.             //position = 0  
  9.             buffer.flip();  
  10.             System.out.println(charset.decode(buffer));  
  11.             //4.position = 0, limit=capacity  
  12.             buffer.clear();   
  13.         }  
  14.         //..省略  

                      1.初始化容量为 4的Buffer  Buffer 数组全部是空的

                            

                             2.调用Channel的read方法  向缓冲区写入2个字节

                              

                           3.如果这个时候调用 Buffer get方法 读的是position =2 limit=3之间的数据

                               
                        4.调用 Buffer #flip方法之后

                           

                          5.再一次调用Buffer get方法

                             

                             6.Buffer clean方法