Java NIO ByteBuffer概述

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ù)的后面。

Buffer-process.jpeg

四個主要屬性:

  • 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相等。


Buffer-put.png

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;
 }
Buffer-flip.png

get

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


Buffer-get.png

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;
    }
Buffer-clear.png

參考:
http://ifeve.com/buffers/
博客:
http://yany8060.xyz/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

  • Java NIO(New IO)是從Java 1.4版本開始引入的一個新的IO API,可以替代標準的Java I...
    JackChen1024閱讀 7,941評論 1 143
  • Java NIO中的Buffer用于和NIO通道進行交互。如你所知,數(shù)據(jù)是從通道讀入緩沖區(qū),從緩沖區(qū)寫入到通道中的...
    AFinalStone閱讀 323評論 0 0
  • 前篇 我一直猜想,除了周圍纏繞著我們的生活,是不是還有另一個世界呢。
    洪濤閱讀 272評論 0 0
  • 看到了這條信息,我很無奈,不知道怎么回答,因為一個回答對她來說沒有什么幫助的,接下來還會有無窮的問題 難道我們在生...
    樂活雅閱讀 3,804評論 0 1
  • 今天,心情頗有些不平靜,些許惆悵,夾雜著憂傷。 也許這才是真實面具下的自己吧,卸去了偽裝,有的只是無盡的孤獨與...
    淺淺微笑的時光閱讀 223評論 2 1

友情鏈接更多精彩內(nèi)容