Buffer的基本用法
使用Buffer讀寫數(shù)據(jù)一般遵循以下四個步驟:
1、分配空間
2、寫入數(shù)據(jù)到Buffer
3、調(diào)用flip()方法
4、從Buffer中讀取數(shù)據(jù)
5、調(diào)用clear()方法或者compact()方法
當向buffer寫入數(shù)據(jù)時,buffer會記錄下寫了多少數(shù)據(jù)。一旦要讀取數(shù)據(jù),需要通過flip()方法將Buffer從寫模式切換到讀模式。在讀模式下,可以讀取之前寫入到buffer的所有數(shù)據(jù)。
一旦讀完了所有的數(shù)據(jù),就需要清空緩沖區(qū),讓它可以再次被寫入。有兩種方式能清空緩沖區(qū):調(diào)用clear()或compact()方法。clear()方法會清空整個緩沖區(qū)。compact()方法只會清除已經(jīng)讀過的數(shù)據(jù)。任何未讀的數(shù)據(jù)都被移到緩沖區(qū)的起始處,新寫入的數(shù)據(jù)將放到緩沖區(qū)未讀數(shù)據(jù)的后面。

四個主要屬性:
- capacity:作為一個內(nèi)存塊,Buffer有一個固定的大小值,也叫“capacity”.你只能往里寫capacity個byte、long,char等類型。一旦Buffer滿了,需要將其清空(通過讀數(shù)據(jù)或者清除數(shù)據(jù))才能繼續(xù)寫數(shù)據(jù)往里寫數(shù)據(jù)。
- position:
- 當你寫數(shù)據(jù)到Buffer中時,position表示當前的位置。初始的position值為0.當一個byte、long等數(shù)據(jù)寫到Buffer后, position會向前移動到下一個可插入數(shù)據(jù)的Buffer單元。position最大可為capacity – 1。
- 當讀取數(shù)據(jù)時,也是從某個特定位置讀。當將Buffer從寫模式切換到讀模式,position會被重置為0。 當從Buffer的position處讀取數(shù)據(jù)時,position向前移動到下一個可讀的位置。
- limit:
- 在寫模式下,Buffer的limit表示你最多能往Buffer里寫多少數(shù)據(jù)。 寫模式下,limit等于Buffer的capacity。
- 當切換Buffer到讀模式時, limit表示你最多能讀到多少數(shù)據(jù)。因此,當切換Buffer到讀模式時,limit會被設置成寫模式下的position值。換句話說,你能讀到之前寫入的所有數(shù)據(jù)(limit被設置成已寫數(shù)據(jù)的數(shù)量,這個值在寫模式下就是position)
- mark:為某一讀過的位置做標記,便于某些時候回退到該位置。
Buffer基本函數(shù)
Buffer的分配
ByteBuffer buf = ByteBuffer.allocate(48);
向Buffer中寫數(shù)據(jù)
從Channel寫到Buffer的例子
int bytesRead = inChannel.read(buf); //read into buffer.
通過put方法寫B(tài)uffer
buf.put(127);
從Buffer中讀取數(shù)據(jù)
從Buffer讀取數(shù)據(jù)到Channel的例子:
//read from buffer into channel.
int bytesWritten = inChannel.write(buf);
使用get()方法從Buffer中讀取數(shù)據(jù)的例子
byte aByte = buf.get();
flip()方法
flip方法將Buffer從寫模式切換到讀模式。調(diào)用flip()方法會將position設回0,并將limit設置成之前position的值。
換句話說,position現(xiàn)在用于標記讀的位置,limit表示之前寫進了多少個byte、char等 —— 現(xiàn)在能讀取多少個byte、char等。
clear()與compact()方法
一旦讀完Buffer中的數(shù)據(jù),需要讓Buffer準備好再次被寫入。可以通過clear()或compact()方法來完成。
如果調(diào)用的是clear()方法,position將被設回0,limit被設置成 capacity的值。換句話說,Buffer 被清空了。Buffer中的數(shù)據(jù)并未清除,只是這些標記告訴我們可以從哪里開始往Buffer里寫數(shù)據(jù)。
如果Buffer中有一些未讀的數(shù)據(jù),調(diào)用clear()方法,數(shù)據(jù)將“被遺忘”,意味著不再有任何標記會告訴你哪些數(shù)據(jù)被讀過,哪些還沒有。
如果Buffer中仍有未讀的數(shù)據(jù),且后續(xù)還需要這些數(shù)據(jù),但是此時想要先先寫些數(shù)據(jù),那么使用compact()方法。
compact()方法將所有未讀的數(shù)據(jù)拷貝到Buffer起始處。然后將position設到最后一個未讀元素正后面。limit屬性依然像clear()方法一樣,設置成capacity?,F(xiàn)在Buffer準備好寫數(shù)據(jù)了,但是不會覆蓋未讀的數(shù)據(jù)。
圖解ByteBuffer函數(shù)過程
put
Writes the given byte into this buffer at the current position, and then increments the position.
寫模式下,往buffer里寫一個字節(jié),并把postion移動一位。寫模式下,一般limit與capacity相等。

flip
Flips this buffer. The limit is set to the current position and then the position is set to zero. If the mark is defined then it is discarded.
After a sequence of channel-read or put operations, invoke this method to prepare for a sequence of channel-write or relative get operations.(即讀寫模型切換)
寫完數(shù)據(jù),需要開始讀的時候,將postion復位到0,并將limit設為當前postion
public final Buffer flip() {
limit = position;
position = 0;
mark = -1;
return this;
}

get
Reads the byte at this buffer's current position, and then increments the position.
從buffer里讀一個字節(jié),并把postion移動一位。上限是limit,即寫入數(shù)據(jù)的最后位置

clear
Clears this buffer. The position is set to zero, the limit is set to the capacity, and the mark is discarded.
Invoke this method before using a sequence of channel-read or put operations to fill this buffer.
將position置為0,并不清除buffer內(nèi)容。
public final Buffer clear() {
position = 0;
limit = capacity;
mark = -1;
return this;
}
