Java NIO之Buffer
Java傳統的I/O模型是面向單個字節的,它將輸入輸出抽象為字節流或字符流。這種單個字節的讀取或寫入模型的效率比較低,而且不符合操作系統的I/O特點。操作系統的IO是面向字節塊的,通常是直接從磁盤中讀取一塊數據到內存或寫入一塊數據到磁盤。Java NIO提供了緩沖區來實現字節塊的讀寫。
Buffer內部管理着一個數組,數據存放在數組中。Buffer作為數據的載體,Java程序在使用NIO時都會通過Buffer與外界進行通信。
一.緩沖區的類別
如上圖所示,除了boolean類型外,Java為其他七種基本類型提供了相應的Buffer。這七種Buffer中,ByteBuffer是最基本的Buffer,其他的類的Buffer可以通過ByteBuffer轉換得到。而且在使用通道對外傳輸數據時,要求必須是ByteBuffer。
二.緩沖區的四種屬性
1.capacity
容量表示緩沖的大小,其實就是緩沖區內部數組的大小。
2.position
位置表示緩沖區中當前可讀寫位置。當調用get()、put()等函數進行讀寫時,會自動更新position。
3.limit
limit表示緩沖區中可用元素的大小。當寫緩沖區時,limit等於capacity,表示整個緩沖區都可寫。當讀緩沖區時,limit是緩沖區中已有元素的大小,表示讀取緩沖區的位置不能超過limit。
4.mark
mark是備忘位置,可以暫時存儲position,以便position改變后可以恢復到原來的位置。
三、Buffer的API
- capacity()返回緩沖區的容量。
- position()返回當前的位置,而position(int)可以設置新的位置,如果給定的參數超過了limit或小於0,會拋出IllegalArgumentException,另外position小於mark,會把mark置為-1,因此在緩沖區使用過程中會一直保持mark<=position<=limit。
- limit()直接返回limit屬性值。
- limit(int)會設置新的limit值,如果新的limit超過了capacity會拋出IllegalArgumentException,如果小於position,則會把position設置為limit,如果小於mark,則mark設為無效值-1。
- mark()方法會把當前position記錄到mark屬性,而reset()方法會把position值設置為mark。
- clear()將Buffer置為初始狀態,position置為0,limit設置為capacity,mark設置為-1。通常在寫入數據之前需要調用該方法。
- flip()表面意思是“翻轉”,生動的描述了Buffer從寫狀態進入讀狀態,該方法會將limit設置為position,同時position設置為0,mark置為-1。
- rewind()方法將position設置為0,以便能重頭開始讀寫數據。
- remaining()返回緩沖區剩余元素的大小,limit-position。hashRemaining()表示緩沖區是否還有剩余元素。
四.Buffer的讀寫
ByteBuffer的讀數據API如下:
Buffer類沒有讀寫相關的API,其各個子類中才有相應的API,這是因為Buffer的子類存儲的類型各不相同,不能作為公共API放到Buffer中。在ByteBuffer中有四種方法可以讀取數據:
- get()從當前位置獲取一個字節,並將position移動到下一個位置。