Java I/O緩沖區(qū)

2018-02-05 18:03 更新

Java IO教程 - Java I/O緩沖區(qū)

什么是NIO?

在NIO中,我們處理I/O操作的通道和緩沖區(qū)。

像流一樣的通道表示數據源/接收器和用于數據傳輸的Java程序之間的連接。

通道提供雙向數據傳輸設施。我們可以使用通道來讀取數據以及寫入數據。根據我們的需要,我們可以獲得只讀通道,只寫通道或讀寫通道。

在基于流的I/O中,數據傳輸的基本單位是一個字節(jié)。在基于通道的NIO中,數據傳輸的基本單位是緩沖器。

緩沖區(qū)具有確定其可以包含的數據的上限的固定容量。

在基于通道的I/O中,我們將數據寫入緩沖區(qū),并將該緩沖區(qū)傳遞到寫入數據的通道。

為了從數據源讀取數據,我們向一個通道傳遞一個緩沖區(qū)。通道將數據從數據源讀入緩沖區(qū)。


緩沖區(qū)

緩沖區(qū)是固定長度的數據容器。有一個單獨的緩沖區(qū)類型來保存每種類型的基本值的數據,除了布爾類型值。

緩沖區(qū)是我們程序中的一個對象。我們有一個單獨的類來表示每種類型的緩沖區(qū)。

所有緩沖區(qū)類都繼承自一個抽象的Buffer類。包含原始值的緩沖區(qū)類如下:

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

不同的緩沖區(qū)保存不同數據類型的數據。例如,ByteBuffer保存字節(jié)值; ShortBuffer保存短值;一個CharBuffer保存字符,等等。


緩沖區(qū)屬性

以下是緩沖區(qū)的四個重要屬性。

  • Capacity
  • Position
  • Limit
  • Mark

緩沖區(qū)的容量是它可以容納的元素的最大數量。并且當創(chuàng)建緩沖器時它是固定的。

我們可以通過調用hasArray()方法檢查緩沖區(qū)是否由數組支持,如果緩沖區(qū)由數組支持則返回true。

我們可以通過使用緩沖對象的array()方法來訪問支持數組。

一旦我們訪問了后臺數組,對該數組所做的任何更改都將反映在緩沖區(qū)中。

緩沖區(qū)具有返回其容量的capacity()方法。

緩沖區(qū)創(chuàng)建

我們可以使用特定緩沖區(qū)類的allocate()工廠方法創(chuàng)建一個緩沖區(qū),如下所示:

以下代碼創(chuàng)建一個容量為8的字節(jié)緩沖區(qū)

ByteBuffer bb  = ByteBuffer.allocate(8);

獲得容量

int capacity = bb.capacity();

以下代碼創(chuàng)建一個容量為1024的字符緩沖區(qū)

CharBuffer cb  = CharBuffer.allocate(1024);

字節(jié)緩沖區(qū)有一個名為allocateDirect()的方法,它創(chuàng)建一個字節(jié)緩沖區(qū),從操作系統(tǒng)內存中分配內存,而不是從JVM堆中分配內存。

我們可以使用ByteBuffer類的isDirect()方法來檢查緩沖區(qū)是直接還是非直接。

// Create a  direct byte   buffer of  512  bytes capacity
ByteBuffer bbd = ByteBuffer.allocateDirect(512);

另一種創(chuàng)建緩沖區(qū)的方法是使用緩沖區(qū)的static wrap()方法包裝數組。

byte[]  byteArray = new byte[512];
ByteBuffer bb  = ByteBuffer.wrap(byteArray);

我們可以使用相同的技術來創(chuàng)建緩沖區(qū)來存儲其他原始值。

當我們創(chuàng)建一個緩沖區(qū)時,緩沖區(qū)的所有元素都被初始化為零值。

緩沖區(qū)索引位置

緩沖區(qū)的每個元素都有一個索引。第一個元素的索引為0,最后一個元素的索引為capacity-1。

創(chuàng)建緩沖區(qū)時,其位置設置為0,其限制等于其容量。

我們可以使用它的重載position()方法獲取/設置緩沖區(qū)的位置。

position()方法返回緩沖區(qū)位置的當前值。

position(int newPosition)方法將緩沖區(qū)的位置設置為指定的newPosition值,并返回緩沖區(qū)的引用。

我們可以使用它的重載limit()方法獲取/設置緩沖區(qū)的限制。

limit()方法返回緩沖區(qū)限制的當前值。limit(int newLimit)方法將緩沖區(qū)的限制設置為指定的newLimit值,并返回緩沖區(qū)的引用。

我們可以使用mark()方法為緩沖區(qū)的位置添加書簽。當我們調用mark()方法時,緩沖區(qū)將其位置的當前值存儲為其標記值。我們可以通過使用reset()方法將緩沖區(qū)的位置設置為之前加書簽的值。

緩沖區(qū)的標記在創(chuàng)建時未定義。只有當定義了它的標記時,我們才必須在緩沖區(qū)上調用reset()方法。否則,reset()方法會拋出InvalidMarkException異常。

以下代碼創(chuàng)建一個新緩沖區(qū)并顯示其四個屬性。

import java.nio.ByteBuffer;
import java.nio.InvalidMarkException;

public class Main {
  public static void main(String[] args) {
    ByteBuffer bb = ByteBuffer.allocate(8);

    System.out.println("Capacity: " + bb.capacity());
    System.out.println("Limit: " + bb.limit());
    System.out.println("Position: " + bb.position());

    // The mark is not set for a new buffer. Calling the
    // reset() method throws a runtime exception if the mark is not set.
    try {
      bb.reset();
      System.out.println("Mark: " + bb.position());
    } catch (InvalidMarkException e) {
      System.out.println("Mark is not  set");
    }
  }
}

上面的代碼生成以下結果。

以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號