Java NIO - Buffer(缓冲)

  • 简述

    Java NIO 中的缓冲区可以被视为一个简单的对象,它充当固定大小的数据块容器,可用于将数据写入通道或从通道读取数据,以便缓冲区充当通道的端点。
    它提供了一组方法,可以更方便地处理内存块,以便从通道读取和写入数据。
    与经典IO相比,缓冲区使NIO包更加高效和快速,因为在IO数据的情况下,数据以不支持异步和并发数据流的流的形式处理。此外,IO 不允许以块或字节组的形式执行数据。
    定义 Java NIO 缓冲区的主要参数可以定义为 −
    • Capacity − 缓冲区中可以存储的最大数据量/字节数,缓冲区的容量无法更改。一旦缓冲区已满,就应该在写入缓冲区之前将其清除。
    • Limit − 根据缓冲区的模式,限制的含义,即在缓冲区限制的写入模式下等于容量,这意味着可以在缓冲区中写入的最大数据。在缓冲区读取模式下,限制意味着可以从缓冲区读取的数据量的限制。
    • Position − 指向缓冲区中光标的当前位置。在创建缓冲区时最初设置为 0,换句话说,它是下一个要读取或写入的元素的索引,该元素通过 get() 和 put() 方法自动更新。
    • Mark ― 标记缓冲区中该位置的书签。当调用 mark() 方法时,记录当前位置,当调用 reset() 时,标记的位置被恢复。
  • 缓冲器类型

    Java NIO 缓冲区可以根据缓冲区处理的数据类型对以下变体进行分类 −
    • ByteBuffer
    • MappedByteBuffer
    • CharBuffer
    • DoubleBuffer
    • FloatBuffer
    • IntBuffer
    • LongBuffer
    • ShortBuffer
  • 缓冲区的重要方法

    如前所述,Buffer充当内存对象,它提供了一组方法,使处理内存块更加方便。以下是缓冲区的重要方法 −
    • allocate(int capacity) − 此方法用于分配以容量为参数的新缓冲区。分配方法在传递的容量为负整数的情况下引发非法参数异常。
    • read() 和 put() − 通道的读取方法用于将数据从通道写入缓冲区,而 put 是一种缓冲区方法,用于在缓冲区中写入数据。
    • flip() − 翻转方法将缓冲区的模式从写入模式切换到读取模式。它还将位置设置回 0,并将限制设置为写入时位置的位置。
    • write() 和 get() − 通道的写入方法用于将数据从缓冲区写入通道,而 get 是一种缓冲区方法,用于从缓冲区读取数据。
    • rewind() − 当需要重读时使用倒带方法,因为它将位置设置回零并且不改变极限值。
    • clear() 和 compact() − 清除和紧凑这两种方法都用于使缓冲区从读到写模式。clear() 方法使位置为零且极限等于容量,在此方法中,缓冲区中的数据未清除,只有标记被重新初始化。
      另一方面,compact()方法在仍有一些未读数据时使用,在这种情况下,我们仍然使用缓冲区的写入模式,在这种情况下,compact方法将所有未读数据复制到缓冲区的开头,并将位置设置为最后一个未读元素之后的右侧。限制属性仍设置为容量。
    • mark() 和 reset() − 顾名思义,标记方法用于标记缓冲区中的任何特定位置,同时重置将位置恢复到标记的位置。
  • 下面的示例演示上述已定义方法的实现。
    
    import java.nio.ByteBuffer;
    import java.nio.CharBuffer;
    public class BufferDemo {
       public static void main (String [] args) {
          //allocate a character type buffer.
          CharBuffer buffer = CharBuffer.allocate(10);
          String text = "bufferDemo";
          System.out.println("Input text: " + text);
          for (int i = 0; i < text.length(); i++) {
             char c = text.charAt(i);
             //put character in buffer.
               buffer.put(c);
          }
          int buffPos = buffer.position();
          System.out.println("Position after data is written into buffer: " + buffPos);
          buffer.flip();
          System.out.println("Reading buffer contents:");
          while (buffer.hasRemaining()) {
             System.out.println(buffer.get());                   
          }
          //set the position of buffer to 5.
          buffer.position(5);
          //sets this buffer's mark at its position
          buffer.mark();
          //try to change the position
          buffer.position(6);
          //calling reset method to restore to the position we marked.
          //reset() raise InvalidMarkException if either the new position is less
          //than the position marked or merk has not been setted.
          buffer.reset();
          System.out.println("Restored buffer position : " + buffer.position());
       }
    }
    
  • 输出

    
    Input text: bufferDemo
    Position after data is written into buffer: 10
    Reading buffer contents:
    b
    u
    f
    f
    e
    r
    D
    e
    m
    o
    Restored buffer position : 5