Java NIO - 緩衝區



Java NIO 中的緩衝區可以被視為一個簡單的物件,它充當資料塊的固定大小容器,可用於將資料寫入通道或從通道讀取資料,因此緩衝區充當通道的端點。

它提供了一組方法,使處理記憶體塊以讀取和寫入通道的資料更加方便。

與經典 IO 相比,緩衝區使 NIO 包更有效率和更快,因為在 IO 的情況下,資料以流的形式處理,不支援資料的非同步和併發流。此外,IO 不允許以塊或位元組組的形式執行資料。

定義 Java NIO 緩衝區的主要引數可以定義為:

  • 容量 - 緩衝區中可以儲存的最大資料/位元組量。緩衝區的容量無法更改。一旦緩衝區已滿,則應在寫入之前將其清空。

  • 限制 - 限制的含義取決於緩衝區的模式,即在緩衝區的寫入模式下,限制等於容量,這意味著可以寫入緩衝區的最大資料量。而在緩衝區的讀取模式下,限制表示可以從緩衝區讀取的資料量。

  • 位置 - 指向緩衝區中游標的當前位置。最初在建立緩衝區時設定為 0,或者換句話說,它是下一個要讀取或寫入的元素的索引,該索引會由 get() 和 put() 方法自動更新。

  • 標記 - 在緩衝區中標記位置的書籤。當呼叫 mark() 方法時,記錄當前位置,當呼叫 reset() 時,恢復標記的位置。

緩衝區型別

根據緩衝區處理的資料型別,Java NIO 緩衝區可以分為以下變體:

  • ByteBuffer
  • MappedByteBuffer
  • CharBuffer
  • DoubleBuffer
  • FloatBuffer
  • IntBuffer
  • LongBuffer
  • ShortBuffer

緩衝區的重要方法

如前所述,緩衝區充當記憶體物件,它提供了一組方法,使處理記憶體塊更加方便。以下是緩衝區的重要方法:

  • allocate(int capacity) - 此方法用於分配一個新的緩衝區,其容量作為引數。如果傳遞的容量為負整數,則 allocate 方法會丟擲 IllegalArgumentException。

  • read() 和 put() - 通道的 read 方法用於將資料從通道寫入緩衝區,而 put 是緩衝區的方法,用於將資料寫入緩衝區。

  • flip() - flip 方法將緩衝區的模式從寫入模式切換到讀取模式。它還將位置重置為 0,並將限制設定為寫入時位置所在的位置。

  • write() 和 get() - 通道的 write 方法用於將資料從緩衝區寫入通道,而 get 是緩衝區的方法,用於從緩衝區讀取資料。

  • rewind() - 當需要重新讀取時使用 rewind 方法,因為它將位置重置為零,並且不更改限制的值。

  • clear() 和 compact() - clear 和 compact 這兩種方法都用於將緩衝區從讀取模式更改為寫入模式。clear() 方法將位置設定為零,並將限制設定為容量,在此方法中,緩衝區中的資料不會被清除,只有標記會重新初始化。

    另一方面,compact() 方法用於當仍有一些未讀取的資料並且我們仍然使用緩衝區的寫入模式時,在這種情況下,compact 方法會將所有未讀取的資料複製到緩衝區的開頭,並將位置設定為最後一個未讀取元素之後。limit 屬性仍設定為容量。

  • mark() 和 reset() - 顧名思義,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
廣告