Java NIO 的緩衝區 Buffer 是什麼?

By | 2017-12-11

本篇是有關 Java NIO 的 Buffer 類別,請先參考先前的文章,先認識 Java NIO:

Java的NIO,什麼是blocking? 什麼是non-blocking?

緩衝區Buffer

Buffer 是 NIO 的一個重要的類別,其角色是介於遠端資料來源端與程式之間的「緩衝區」,當從 Channel 讀取資料時,先將資料置於 Buffer 中,程式再從 Buffer 中讀取資料。如下圖:

java.nio.Buffer 是個抽象類別,它制定了緩衝區該有的屬性與方法,並成為許多各類型緩衝區類別的父類別,例如專門用來存放位元組的ByteBuffer、存放字元的CharBuffer 等,常用的緩衝區類別有七種,分別對應除了布林值外的七個基本資料型別。

緩衝區的分類

緩衝區有「直接緩衝區」與「間接緩衝區」兩大類,直接緩衝區可跳過 JVM 的處理,直接對應到作業系統的記憶體來存取緩衝區資料,適合較大檔案或需要長存活時間的需求,因為 JVM 通常會因為本身被限制的記憶體使用量,而影響緩衝區的使用量。而間接緩衝區則是由 JVM 負責所有的容量分配與存取動作,使用上會耗費 JVM 本身所分配的記憶體,相對的比直接緩衝區的限制要來得多。

在實務的設計中,除非要存取的檔案較大,否則皆不採用直接緩衝區,因為在取得或清除該緩衝區時會花費較多的時間。通常都採用間接緩衝區來處理,產生間接緩衝區的方式是呼叫 Buffer 的靜態方法 allocate 來得到物件,例如要得到一個可容納 10 個 byte 的緩衝區物件:

要得到直接緩衝區的物件時,則要呼叫 ByteBuffer 的靜態方法 allocatDirect :

ByteBuffer buf = ByteBuffer.allocateDirect(20);

而且只能由 ByteBuffer 產生直接緩衝區(只有 ByteBuffer 有 allocateDirect 方法),再由 ByteBuffer 進行轉型得到其他類型的緩衝區,且 Buffer 皆可使用 isDirect() 得到目前的緩衝區是否為直接緩衝區:

程式執行結果:

產生ByteBuffer

產生 ByteBuffer 有三種方式,除了上述呼叫 ByteBuffer 類別的靜態方法 allocate 以外,還可以由已存在的 byte 陣列「包裝(wrap)」而得到,另外使用 FileChannel 的 map 方法,則可將檔案資料對應成為緩衝區。

將資料放入緩衝區

準備好緩衝區物件後,可使用 put 方法將資料放入緩衝區,各個 put 方法的使用說明如下:

  • ByteBuffer put(byte[] src)

將一個 byte 陣列的資料放入緩衝區,並回傳該緩衝區,例如:

buf的內容將成為:

  • ByteBuffer put(byte[] src, int offset, int length)

將 byte 陣列中特定範圍的元素放入緩衝區,從陣列的 offset 位置開始取得 length 個元素,並回傳該緩衝區,例如取得 “abcxyz” 字串中的 “yz”,並放入 ByteBuffer 中:

buf 的內容將成為:

  • ByteBuffer put(ByteBuffer src)

將另一個 ByteBuffer 的內容放到目前的 ByteBuffer 中,回傳該緩衝區,例如將一個緩衝區 buf 的內容放到另一個 buf2 中:

buf2 的內容將成為:

 

相關文章:

Category: Java NIO 標籤:, ,

About Hank Tom

專長為程式語言、雲端服務開發,Linux系統管理, 任職:利拓科技 技術長,海林行動科技 技術總監 輔仁大學 兼任助理教授 , 為 Android高效入門>深度學習、CentOS 7建置、管理與伺服器架設實戰、Java網路程式設計、雲端網頁程式設計-Google App Engine應用實作 等書作者

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *