📜  Java NIO-缓冲区

📅  最后修改于: 2020-11-14 10:13:59             🧑  作者: Mango


Java NIO中的缓冲区可以视为一个简单的对象,它充当固定大小的数据块容器,可用于将数据写入通道或从通道中读取数据,以便缓冲区充当通道的端点。

它提供了一套方法,可以更方便地处理内存块,以便在通道之间读写数据。

与传统IO相比,缓冲区使NIO包更高效,更快,因为IO数据以不支持异步和并发数据流的流形式进行处理,并且IO不允许以块或字节组的形式执行数据。

定义Java NIO缓冲区的主要参数可以定义为-

  • 容量-缓冲区中可以存储的最大数据量/字节数。缓冲区的容量不可更改,一旦缓冲区已满,应在写入之前将其清除。

  • 限制-限制的含义与缓冲区的模式相同,即在缓冲区的写模式下,Limit等于容量,这意味着可以在缓冲区中写入的最大数据。在缓冲区的读取模式下,Limit表示可以限制的数据量从缓冲区读取。

  • 位置-指向光标在缓冲区中的当前位置。在创建缓冲区时最初设置为0,换句话说,它是要读取或写入的下一个元素的索引,该元素由get()自动更新并放入() 方法。

  • 标记-在缓冲区中标记该位置的书签。调用mark()方法时,将记录当前位置,而当调用reset()时,将还原标记的位置。

缓冲区类型

Java NIO缓冲区可以根据缓冲区处理的数据类型分为以下几种:

  • 字节缓冲区
  • MappedByteBuffer
  • 字符缓冲区
  • 双缓冲
  • FloatBuffer
  • IntBuffer
  • 长缓冲
  • 短缓冲区

缓冲的重要方法

前面已经提到Buffer充当内存对象,它提供了一组更便于处理内存块的方法。以下是Buffer的重要方法-

  • allocate(int Capacity) -此方法用于分配一个以容量为参数的新缓冲区。如果传递的容量为负整数,则Allocate方法将抛出IllegalArgumentException。

  • read()和put() -channel的读取方法用于将数据从通道写入缓冲区,而put是一种缓冲区的方法,用于将数据写入缓冲区。

  • flip() -flip方法将Buffer的模式从写入模式切换到读取模式,还将位置重新设置为0,并将极限值设置为写入时的位置。

  • write()和get() -通道的写入方法用于将数据从缓冲区写入通道,而get是缓冲区的方法,用于从缓冲区读取数据。

  • rewind() -当需要重读时使用rewind方法,因为它将位置重新设置为零并且不更改limit的值。

  • clear()和compact() -清除和压缩这两种方法都用于使缓冲区从读取模式变为写入模式。 clear()方法使位置为零且极限等于容量,在这种方法中,仅重新标记会不会清除缓冲区中的数据。

    另一方面,当仍有一些未读数据并且仍使用缓冲区的写模式时,将使用compact()方法,在这种情况下,compact方法会将所有未读数据复制到缓冲区的开头,并将位置设置为最后一个未读元素之后。limit属性仍设置为容量。

  • mark()和reset() -顾名思义,mark方法用于标记缓冲区中的任何特定位置,同时将位置重置为标记位置。

以下示例显示了上述方法的实现。

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