NIO之Buffer

时间:2014-05-01 07:54:06   收藏:0   阅读:326

Buffer

 

Buffer

Mark<=Position <=Limt<=Capacity

状态变量

在从通道读取时,将所读取的数据放到底层的数组中。 position 变量跟踪已经写了多少数据。它指定了下一个字节将放到数组的哪一个元素中。因此,如果从通道中读三个字节到缓冲区中,那么缓冲区的position 将会设置为3,指向数组中第四个元素。

 一个备忘标记位置调用,mark()函数设置mark=positon,调用reset()设置position=mark。

limit 变量表明还有多少数据需要取出(在从缓冲区写入通道时),或者还有多少空间可以放入数据(在从通道读入缓冲区时)。

缓冲区的 capacity 表明可以储存在缓冲区中的最大数据容量。实际上,它指定了底层数组的大小或者指定了准许使用的底层数组的容量。

图形演示

初始:一个新创建的缓冲区。假设这个缓冲区的 总容量 为8个节。 Buffer 的状态如下所示:

bubuko.com,布布扣

 bubuko.com,布布扣

 bubuko.com,布布扣

第一次写入时,从缓冲区中取四个字节并将它们写入输出通道。这使得 position 增加到 4,而 limit 不变:

 bubuko.com,布布扣

再次写入,只剩下一个字节可写, limit在调用 flip() 时被设置为 5,并且 position 不能超过 limit。所以最后一次写入操作从缓冲区取出一个字节并将它写入输出通道。这使得 position 增加到 5,并保持 limit 不变。

 bubuko.com,布布扣

它将limit设置为与capacity 相同;它设置 position为0;可以再次往缓冲区写数据了。

 bubuko.com,布布扣

缓冲区操作

          bubuko.com,布布扣

     数组和缓冲区共用一分数据。

          bubuko.com,布布扣

       原缓冲区和新的缓冲区分片共享同一个底层数据数组,并且对缓冲区分片的新缓冲区修改只影响子缓冲区。

        bubuko.com,布布扣

        未读的元素移动到下表0开始,position为最后一个未读元素的下一个下标,limit在这个过程中没变化,如果想读取这部分元素,执行一次翻转。

  两个缓冲区相等的充分必要条件:

  1. 两个缓冲区类型必须相同
  2. 两个缓冲区剩余元素数量必须相同,两个缓冲区容量可以不同

  3.  两个缓冲区通过get()取得的元素序列必须相同

bubuko.com,布布扣
@Test
    public void compareBuffer(){
        //cb1和cb2的capacity不相等
        CharBuffer cb1=CharBuffer.allocate(10);
        CharBuffer cb2=CharBuffer.allocate(8);
        for (int i=65;i<75;i++){
            cb1.put((char)i);
        }
        for (int j=69;j<75;j++){
            cb2.put((char)j);
        }
        cb1.flip();
        cb2.flip();
        System.out.println("original cb1:"+Arrays.toString(cb1.array()));
        System.out.println("original cb2:"+Arrays.toString(cb2.array()));
        //cb1读取六个元素
        for(int m=0;m<5;m++){
           cb1.get();
        }
        //cb2读取一个元素
        cb2.get();
        System.out.println(cb1.equals(cb2));
    }
bubuko.com,布布扣

     运行结果:

       bubuko.com,布布扣

只读缓冲区

直接缓冲区

    给定一个直接字节缓冲区,Java 虚拟机将尽最大努力直接对它执行本机 I/O 操作。也就是说,它会在每一次调用底层操作系统的本机 I/O 操作之前(或之后),尝试避免将缓冲区的内容拷贝到一个中间缓冲区中(或者从一个中间缓冲区中拷贝数据)

bubuko.com,布布扣
/**
     * 直接缓冲区
     * @throws Exception
     */
    @Test
    public void directBuffer() throws Exception {
        FileInputStream fi = new FileInputStream(this.sourcePath);
        FileOutputStream fo = new FileOutputStream(this.destPath);
        ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024);
        FileChannel fic = fi.getChannel();
        FileChannel foc = fo.getChannel();
        while (fic.read(directBuffer) != -1) {
            directBuffer.flip();
            foc.write(directBuffer);
            directBuffer.clear();
        }
        fi.close();
        fo.close();
    }
bubuko.com,布布扣

内存映像

     内存映射文件 I/O 是通过使文件中的数据出现为内存数组的内容来完成的。一般来说,只有文件中实际读取或者写入的部分才会送入(或者 映射 )到内存中。

只能通过FileChannel来创建。

    代码实例:

bubuko.com,布布扣
public void mappedByteBuffer() throws  Exception{
        FileInputStream fi = new FileInputStream(this.sourcePath);
        //MappedByteBuffer是ByteBuffer的子类。
        MappedByteBuffer mappedByteBuffer=fi.getChannel().map(FileChannel.MapMode.READ_ONLY,0l,1024l);

    }
bubuko.com,布布扣

字节缓冲区

  1. 大端字节

        bubuko.com,布布扣

       2.  小端字节

          bubuko.com,布布扣

         获取本地字节顺序:ByteOrder.nativeOrder();

    

bubuko.com,布布扣
 /**
     * 字节顺序
     */
    @Test
    public void byteOrder(){
        System.out.println("My mac pro byte order:"+ByteOrder.nativeOrder());
    }
bubuko.com,布布扣

        运行结果:

        bubuko.com,布布扣

     

视图缓冲区

     

bubuko.com,布布扣
/**
     * 视图buffer
     */
    @Test
    public void viewBuffer() {
        this.byteOrder();
        ByteBuffer bb = ByteBuffer.allocate(16).order(ByteOrder.BIG_ENDIAN);
        CharBuffer cb=bb.asCharBuffer();
        bb.put((byte)0);
        bb.put((byte)‘r‘);
        bb.put((byte)0);
        bb.put((byte)‘e‘);
        bb.put((byte)0);
        bb.put((byte)‘q‘);
        bb.put((byte)0);
        bb.put((byte)‘u‘);
        bb.put((byte)0);
        bb.put((byte)‘e‘);
        bb.put((byte)0);
        bb.put((byte)‘l‘);
        bb.put((byte)0);
        bb.put((byte)‘q‘);
        bb.put((byte)0);
        bb.put((byte)‘i‘);
        System.out.println("original bb position:"+bb.position()+",limit:"+bb.limit()+",bb is:"+Arrays.toString(bb.array()));
        System.out.println("view buffer cb position:"+cb.position()+",limit:"+cb.limit()+",bb is:"+cb.toString());
    }
bubuko.com,布布扣

     运行结果:

    bubuko.com,布布扣

NIO之Buffer,布布扣,bubuko.com

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!