Java NIO 學習

shengmeitang發表於2013-06-26

Buffer快取區,為Java NIO中進行操作的資料來源;除boolean型別之外Java的基本資料型別都有對應的實現,外加MappedByteBuffer。

Java NIO加強了與底層作業系統的結合,以提升讀寫速度;作業系統處理資料是以byte(位元組)為單位來進行的,因此ByteBuffer佔有非常重要的地位,其他型別的Buffer可轉換為ByteBuffer來進行操作(ByteBuffer中提供了相應方法)。

以ByteBuffer為例:

快取區為記憶體分配上的一段儲存空間,存在容量(capacity)、上限(limit)、位置(position)、標記(mark)。

Capacity:為緩衝區容量,在建立緩衝區時進行設定,之後不能改變

Limit:緩衝區上限,之後無法再進行讀寫,可以改變。

Position:位置,下一個要進行讀/寫的元素索引,會根據get()、put()方法自動改變。

mark:一個備忘位置,使用mark()進行設定mark = position 使用reset() 重置 position = mark

其讀寫資料依靠get()、put()方法(每個子類都有不同實現,因此get、put方法不存在於Buffer介面中),批量讀寫資料依靠get(byte[] bytes)、put(byte[] bytes);

緩衝寫入完畢後,position所在位置為下一個將要寫入的元素索引,此時值為空,若要對該緩衝區進行讀操作,需要對其進行翻轉,將limit設為當前position所在位置,position位置設為0,可通過flip()方法進行實現。

Buffer的equal()方法:

若返回true,需要條件為:1、型別相同2、緩衝區內剩餘元素數量相同,緩衝區屬性可以不同3、元素輸出順序相同

緩衝區的建立方式:

1、allocate(),分配操作建立一個緩衝區,建立一個私有空間

2、wrap(),包裝操作建立一個緩衝區,建立緩衝區物件但不分配空間,使用提供的陣列儲存緩衝區內容

之上兩種方式建立的都是間接緩衝區,通過使用備份陣列來達到儲存資料的目的,呼叫array()方法可獲取對儲存陣列的引用,對該陣列的操作會直接影響到緩衝區。

緩衝區的複製與分割:

duplicate():返回一個緩衝區物件,與原緩衝區共享資料,繼承原緩衝區只讀等屬性,但有不同的position、mark

asReadOnlyBuffer():與duplicate()返回物件類似,只不過為只讀的

slice():對原緩衝區進行分隔,範圍從當前position到limit,返回的新緩衝區與原緩衝區共享這一段資料

間接緩衝區通過在堆上分配記憶體空間來實現儲存,之上的無論複製緩衝區還是分割緩衝區,都是在已分配好的空間上進行操作。

直接緩衝區:

直接緩衝區是進行IO的最佳選擇,支援JVM能夠實現的IO最高效機制,但分配、銷燬直接緩衝區需要消耗更多的資源,直接緩衝區是在JVM之外進行分配的。

allocateDirect():分配直接緩衝區

非直接緩衝區也可被傳遞給通道,但其執行時需要隱式的構造一個臨時直接緩衝區來進行讀寫操作。

只有位元組能夠被直接分配,也就是說只有ByteBuffer能夠建立直接緩衝區;若基礎緩衝區為直接緩衝區,則根據基礎緩衝區建立的非位元組緩衝區也可視為直接緩衝區。

byte是作業系統進行讀寫操作的基本單位,通道只接受ByteBuffer作為引數,其它型別的緩衝區中的內容需轉換為byte再進行操作。

檢視緩衝區:在已有的ByteBuffer緩衝區的基礎上進行建立,與原緩衝區共享資料,維護自己的Capacity、Limit、Position、Mark。所建立的檢視緩衝區的容量是位元組緩衝區中存在的元素數量除以檢視型別中組成一個資料型別的位元組數


對緩衝區的操作類似於對陣列的操作(緩衝區本質上是由陣列實現的):拷貝、壓縮、分割、共享儲存空間.............

而檢視緩衝區有點類似於IO中的過濾器流,通過檢視緩衝區將位元組轉換為各種各樣的基礎資料型別來進行操作。


相關文章