Java NIO——Buffer


转载自 并发编程网 – ifeve.com本文链接地址: Java NIO系列教程(三) Buffer

1 概述

    Buffer,即缓冲区,主要用于与NIO通道进行交互。数据从Channel读取Buffer,从Buffer写入Channel。
    缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存。这块内存被包装成NIO Buffer对象,并提供了一组方法,用来方便的访问该块内存。
Buffer类型

ByteBuffer
CharBuffer
ShortBuffer
IntBuffer
LongBuffer
FloatBuffer
DoubleBuffer

2 基本属性

capacity
    缓存区的容量,不可改变。只能往里写capacity个byte、int,char等类型。
position
    当你要写数据到Buffer中时,position表示当前可写的位置。初始的position值为0(也可以用过方法进行改变)。当一个byte、int等数据写到Buffer后, position会向前移动到下一个可插入数据的Buffer单元。position最大可为capacity – 1.
    当读取数据时,也是从某个特定位置读。当从Buffer的position处读取数据完成时,position向前移动到下一个可读的位置。
limit
    在写数据时,Buffer的limit表示你最多能往Buffer里写多少数据,position移动到limit写操作停止。初始limit的值等于Buffer的capacity。
    当读取数据时, limit表示你最多能读到多少数据,position移动到limit读操作停止。
无论在读数据时还是在写数据时,只要position超过了limit就会抛出异常。

3 基本用法

使用Buffer读写数据一般遵循以下几个步骤:

  • 1 采用allocate分配一块固定容量的缓冲区。
  • 2 写入数据到Buffer
  • 3 调用flip()方法,从写模式切换到读模式
  • 4 从Buffer中读取数据
  • 5 调用clear()方法或者compact()方法,清空缓冲区数据

3.1 DEMO

String src =  "bufferTest1.txt";
        RandomAccessFile r=null;
        try {
            r = new RandomAccessFile(src,"rw");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        FileChannel channel = r.getChannel();
        // 1. 创建一块大小为8的缓冲区
        ByteBuffer buffer = ByteBuffer.allocate(8);
        int len =0;
        //2. 读入数据到buffer
        while ((len= channel.read(buffer))!=-1){
            //3 切换到读取模式
            buffer.flip();
            while (buffer.hasRemaining()){
                // 4 每次读取一个字节
                byte byte1= buffer.get();
                System.out.println(byte1);
            }
            // 5 清空buffer
            buffer.clear();
        }
        r.close();

3.2 获取buffer

通过allocate()方法分配一个固定容量的buffer

ByteBuffer b = ByteBuffer.allocate(8);

3.3 读取数据到Buffer

写数据到Buffer有两种方式:

  • 从Channel写到Buffer。
  • 通过Buffer的put()方法写到Buffer里。
channel.read(buffer))
buffer.put(some thing);//byte,byte[],buffer等

3.4 flip()

    flip方法将Buffer从写模式切换到读模式。调用flip()方法会将position设回0,并将limit设置成之前position的值。
换句话说,position现在用于标记读的位置,limit表示之前写进了多少个byte、char等 —— 现在能读取多少个byte、char等。

3.5 clear()与compact()

    一旦读完Buffer中的数据,需要让Buffer准备好再次被写入。可以通过clear()或compact()方法来完成。
    如果调用的是clear()方法,position将被设回0,limit被设置成 capacity的值。换句话说,Buffer 被清空了。Buffer中的数据并未清除,只是这些标记告诉我们可以从哪里开始往Buffer里写数据。
    如果Buffer中有一些未读的数据,调用clear()方法,数据将“被遗忘”,意味着不再有任何标记会告诉你哪些数据被读过,哪些还没有。
    如果Buffer中仍有未读的数据,且后续还需要这些数据,但是此时想要先先写些数据,那么使用compact()方法。
   &160;compact()方法将所有未读的数据拷贝到Buffer起始处。然后将position设到最后一个未读元素正后面。limit属性依然像clear()方法一样,设置成capacity。现在Buffer准备好写数据了,但是不会覆盖未读的数据。

3.6mark()与reset()方法

   &160;通过调用Buffer.mark()方法,可以标记Buffer中的一个特定position。之后可以通过调用Buffer.reset()方法恢复到这个position。例如:

buffer.mark();
//call buffer.get() a couple of times, e.g. during parsing.
buffer.reset();  //set position back to mark.

猜你喜欢

转载自blog.csdn.net/ccoran/article/details/84848368