Buffer四個基本屬性
1、capacity:能夠容納的最大元素數目,創建時設定並不能更改
2、limit: buffer中有效位置數目
3、position: 下一個讀或者寫的位置
4、mark: 用於記憶的標誌位,配合reset()使用,初始值未設定,調用mark後將當前position設爲值
標記、位置、限制和容量值有以下關係:
0 <= 標記 <= 位置 <= 限制 <= 容量
Buffer的操作
1、讀取
get(),從當前position位置讀取
get(index),從index位置讀取,不改變當前position
2、寫入
put(byte),在當前position位置填充
put(index,byte),按照絕對位置填充不改變當前position屬性
3、flip
將limit設爲position, 將position設爲0。特別注意,flip()方法會改變limit屬性,將limit屬性從capacity設置爲當前position。兩次調用buffer的flip方法,將使得position和limit屬性都爲0。
4、rewind
與flip()類似,但是僅將position設爲0,而不改變limit,通常用於重新讀取已經被flip的buffer。
5、clear
將buffer重設爲空狀態,也就是設置limit=capacity,position=0,以便重複利用。
6、compact
清除已經讀過的數據,任何未讀的數據都被移到緩衝區的起始處,新寫入的數據將放到緩衝區未讀數據的後面。即將 position 與 limit之間的數據複製到buffer的開始位置,複製後 position = limit -position,limit = capacity。
7、mark與reset
mark初始是未定義的,調用mark後,將當前position設爲mark以便reset時返回。rewind,clear,flip都將丟棄已經創建的mark。調用limit(index),positioon(index),如果index的值小於當前mark,mark也將被丟棄。
8、duplicate與slice
通過duplicate()方法將返回一個新創建的buffer,這個新buffer與原來buffer的視圖,一樣的capacity,但是有自己的position、limit和mark屬性。slice將從原來buffer的當前position開始,並且capacity等於原來Buffer的剩餘元素數目,也就是(limit-position)。
下面給出這幾個方法的調用時buffer的狀態變化
向容量大小爲12的buffer中寫入helloworld,position發生變化
調用flip,準備讀取數據,position和limit發生變化
讀取數據的過程中
remaining爲0時,說明已經讀取完成,此時position和limit重疊。
此時再次調用flip,又可以重新讀取
下面clear buffer中的數據,重新寫入,此時position爲0,limit爲capacity
寫入字符串javanio
此時可以調用flip讀取數據
讀取數據
此時可以通過rewind將position置爲0,重新從頭讀取
當讀到v的時候,mark一下(此時mark=position),下次可以reset之後重新回到mark的位置
繼續讀取
此時reset,可以重新回到原先mark的位置
調用compact,將未讀的數據拷貝到buffer開始處,然後將position設到最後一個未讀元素正後面,limit設置成capacity
這爲buffer中的某一情形,下面調用duplicate或者slice,會產生一個buffer的副本。下圖爲原始的buffer。
調用duplicate,複製出來的buffer其實是一個視圖,複製出來的buffer和原來的buffer擁有相同的數據,但是每個buffer都有各自的屬性。下圖爲duplicate buffer。
調用slice,取緩衝區的一部分
以上演示的圖片來源於Ron Hitchens撰寫的Java Nio這本書的網站。