欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java NIO Buffer過程詳解

 更新時(shí)間:2019年06月13日 10:07:22   作者:xiaoaiwhc1, kevinlinkai, 琪花億草, 溪邊九節(jié)  
這篇文章主要介紹了Java NIO Buffer過程詳解,緩沖區(qū)在java nio中負(fù)責(zé)數(shù)據(jù)的存儲(chǔ)。緩沖區(qū)就是數(shù)組。用于存儲(chǔ)不同數(shù)據(jù)類型的數(shù)據(jù)。,需要的朋友可以參考下

前言

在與NIO通道交互時(shí)使用Java NIO Buffer。 如您所知,數(shù)據(jù)從通道讀入緩沖區(qū),并從緩沖區(qū)寫入通道。

緩沖區(qū)本質(zhì)上是一個(gè)可以寫入數(shù)據(jù)的內(nèi)存塊,然后可以再次讀取。 此內(nèi)存塊包含在NIO Buffer對(duì)象中,該對(duì)象提供了一組方法,可以更輕松地使用內(nèi)存塊。

基本緩沖區(qū)用法

使用緩沖區(qū)讀取和寫入數(shù)據(jù)通常遵循這4個(gè)小步驟:

1.寫入數(shù)據(jù)到緩沖區(qū)

2.調(diào)用 buffer.flip()

3.從緩沖區(qū)讀取數(shù)據(jù)

4.調(diào)用 buffer.clear() 或者 buffer.compact()

當(dāng)你將數(shù)據(jù)寫入Buffer時(shí),Buffer會(huì)跟蹤你已經(jīng)寫入了多少數(shù)據(jù)。一旦你需要讀出數(shù)據(jù),你需要調(diào)用 flip() 方法將Buffer從寫模式轉(zhuǎn)換到讀模式。在讀模式,Buffer允許你將之前寫入的數(shù)據(jù)全部讀出。

一旦你已經(jīng)讀出了所有數(shù)據(jù),你需要清除Buffer,為下次寫入數(shù)據(jù)做準(zhǔn)備??梢酝ㄟ^以下兩種方法來完成:clear() 和 compact()。clear() 方法清除整個(gè)Buffer,而 compact() 方法僅僅清除你已經(jīng)讀出的Buffer,未讀數(shù)據(jù)會(huì)被移動(dòng)到Buffer的開始位置,再次寫入的數(shù)據(jù)會(huì)追加到未讀數(shù)據(jù)的后面。

這是一個(gè)簡(jiǎn)單的 Buffer 使用的例子,使用的 write, flip, read 和 clear 操作:

RandomAccessFile aFile = new RandomAccessFile("data/nio-data.txt", "rw");
FileChannel inChannel = aFile.getChannel();
//create buffer with capacity of 48 bytes
ByteBuffer buf = ByteBuffer.allocate(48);int bytesRead = inChannel.read(buf); //read into buffer.
while (bytesRead != -1) { buf.flip(); //make buffer ready for read
while(buf.hasRemaining()){
System.out.print((char) buf.get()); // read 1 byte at a time
} buf.clear(); //make buffer ready for writing
bytesRead = inChannel.read(buf);
}
aFile.close();

Buffer的三個(gè)屬性:容量,位置和限定符

Buffer本質(zhì)上是一塊你可以寫入數(shù)據(jù)的內(nèi)存區(qū)域,當(dāng)然你也可以在寫入之后讀出數(shù)據(jù)。該內(nèi)存區(qū)域被封裝成一個(gè) NIO Buffer 對(duì)象,它提供一系列的方法,以方便對(duì)該內(nèi)存區(qū)域的操作。

為了學(xué)習(xí)Buffer 是如何工作的,Buffer 的三個(gè)屬性你必須要熟悉,它們是:

  • capacity (容量)
  • position (游標(biāo)位置)
  • limit (末尾限定符)

其中,position 和 limit 的意義依賴于當(dāng)前 Buffer 是處于讀模式還是寫模式。capacity 的含義無論讀寫模式都是相同的。

下面是對(duì)以上三個(gè)屬性在讀模式和寫模式的一個(gè)示例,后面會(huì)有詳細(xì)的解釋:

Buffer capacity, position and limit in write and read mode.

Capacity (容量)

作為一個(gè)內(nèi)存塊,Buffer 有一個(gè)固定的大小,我們叫做 “capacity(容量)"。你最多只能向 Buffer 寫入 capacity 大小的字節(jié),長(zhǎng)整數(shù),字符等。一旦 Buffer 滿了,你必須在繼續(xù)寫入數(shù)據(jù)之前清空它(讀出數(shù)據(jù),或清除數(shù)據(jù))。

Position (游標(biāo)位置)

當(dāng)你開始向 Buffer 寫入數(shù)據(jù)時(shí),你必須知道數(shù)據(jù)將要寫入的位置。position 的初始值為 0。當(dāng)一個(gè)字節(jié)或長(zhǎng)整數(shù)等類似數(shù)據(jù)類型被寫入 Buffer 后,position 就會(huì)指向下一個(gè)將要寫入數(shù)據(jù)的位置(根據(jù)數(shù)據(jù)類型大小計(jì)算)。position 的最大值是 capacity - 1。

當(dāng)你需要從 Buffer 讀出數(shù)據(jù)時(shí),你也需要知道將要從什么位置開始讀數(shù)據(jù)。在你調(diào)用 flip 方法將 Buffer 從寫模式轉(zhuǎn)換為讀模式時(shí),position 被重新設(shè)置為 0。然后你從 position 指向的位置開始讀取數(shù)據(jù),接下來 position 指向下一個(gè)你要讀取的位置。

限制(Limit)

在寫模式下對(duì)一個(gè)Buffer的限制即你能將多少數(shù)據(jù)寫入Buffer中。在寫模式下,限制等同于Buffer的容量(capacity)。

當(dāng)切換Buffer為讀模式時(shí),限制表示你最多能讀取到多少數(shù)據(jù)。因此,當(dāng)切換Buffer為讀模式時(shí),限制會(huì)被設(shè)置為寫模式下的position值。換句話說,你能讀到之前寫入的所有數(shù)據(jù)(限制被設(shè)置為已寫的字節(jié)數(shù),在寫模式下就是position)。

Buffer類型

Java NIO提出了如下幾種Buffer類型:

  • ByteBuffer
  • MappedByteBuffer
  • CharBuffer
  • DoubleBuffer
  • FloatBuffer
  • IntBuffer
  • LongBuffer
  • ShortBuffer

正如你所看到的,這些Buffer類型代表了不同的數(shù)據(jù)類型。換句話說,他們讓你可以在使用的時(shí)候用char, short, int, long, float 或者double類型來代替直接使用buffer中的字節(jié)。

其中MappedByteBuffer有點(diǎn)特殊,將在它自己的部分來闡述。

分配一個(gè)Buffer

若要獲取一個(gè)Buffer對(duì)象,必須先分配它。每個(gè)Buffer類都有allocate()函數(shù)用來分配。下面的例子展示了分配一個(gè)

ByteBuffer,其容量為48字節(jié)。

ByteBuffer buf = ByteBuffer.allocate(48);

下面的例子是分配一個(gè)具有1024個(gè)字符的空間的CharBuffer:

CharBuffer buf = CharBuffer.allocate(1024);

將數(shù)據(jù)寫入Buffer

有兩種方法可以將數(shù)據(jù)寫入Buffer:

1.從Channel將數(shù)據(jù)寫入Buffer

2.調(diào)用buffer的put()函數(shù),自己將數(shù)據(jù)寫入Buffer。

下面的例子是展示Channel如何將數(shù)據(jù)寫入到Buffer中:

int bytesRead = inChannel.read(buf); //read into buffer.

下面的例子是通過put()函數(shù)將數(shù)據(jù)寫入Buffer:

buf.put(127);

put()函數(shù)還有很多其他版本,可以讓你使用不用的方法將數(shù)據(jù)寫入到Buffer。例如,在特定的位置寫,或者將字節(jié)數(shù)組寫入到buffer。查看JavaDoc來了解buffer實(shí)現(xiàn)的更多細(xì)節(jié)。

flip()

用 flip() 方法將 Buffer f從寫入模式切換到讀取模式。調(diào)用 flip() 將 position 設(shè)置回0,并將 limit 置為剛才的位置。

換句話說,position 現(xiàn)在標(biāo)記了讀取位置,limit 標(biāo)記了寫入緩沖區(qū)的字節(jié)、字符數(shù)等——可以讀取的字節(jié)數(shù)、字符數(shù)等的限制。

從緩沖區(qū)讀取數(shù)據(jù)

有兩種方法可以從 Buffer 中讀取數(shù)據(jù)。

1.從緩沖區(qū)讀取數(shù)據(jù)到通道。

2.使用緩沖區(qū)自帶方法中的 get() 方法從緩沖區(qū)讀取數(shù)據(jù)。

下面是如何將數(shù)據(jù)從緩沖區(qū)讀取到通道的例子:

//read from buffer into channel.
int bytesWritten = inChannel.write(buf);

下面是使用 get() 方法從 Buffer 中讀取數(shù)據(jù)的例子:

byte aByte = buf.get();

get() 方法還有許多其他版本,允許您以多種不同的方式從 Buffer 中讀取數(shù)據(jù)。 例如,在特定位置讀取,或者從緩沖區(qū)讀取字節(jié)數(shù)組。有關(guān)具體緩沖區(qū)實(shí)現(xiàn)的詳細(xì)信息,請(qǐng)參閱JavaDoc。

rewind()

Buffer.rewind() 將 position 設(shè)置回0,因此你可以重讀緩沖區(qū)中的所有數(shù)據(jù)。這個(gè) limit 保持不變,因此仍然標(biāo)記有多少元素(字節(jié)、字符等)可以從Buffer讀取。

clear() and compact()

從 Buffer 中讀取數(shù)據(jù)之后,必須讓 Buffer 為再次寫入做好準(zhǔn)備。您可以通過調(diào)用 clear() 或調(diào)用 compact()來做到這一點(diǎn)。

如果您調(diào)用 clear() ,position 將被設(shè)置為0,并 limit 置為 capacity。換句話說,Buffer 被清除。Buffer 中的數(shù)據(jù)沒有清除。只有標(biāo)記告訴您可以將數(shù)據(jù)寫入 Buffer 的位置。

當(dāng)您調(diào)用 clear() 時(shí),如果緩沖區(qū)中有任何未讀數(shù)據(jù),則數(shù)據(jù)將被“遺忘”,這意味著您不再有任何標(biāo)記來說明哪些數(shù)據(jù)已被讀取,哪些數(shù)據(jù)未被讀取。

如果 Buffer 中仍然有未讀數(shù)據(jù),并且您希望稍后讀取它,但是您需要先寫一些東西,那么調(diào)用 compact() 而不是 clear().

compact() 將所有未讀的數(shù)據(jù)復(fù)制到 Buffer 的開頭。然后將 position 設(shè)置為最后一個(gè)未讀元素之后的位置。與 clear() 一樣,limit 屬性仍然設(shè)置為 capacity。現(xiàn)在 Buffer 已經(jīng)準(zhǔn)備好寫入,但是不會(huì)覆蓋未讀數(shù)據(jù)。

mark() and reset()

你可以調(diào)用 Buffer.mark() 方法在 Buffer 中標(biāo)記給定位置。之后,你可以調(diào)用 Buffer.reset() 方法重置回標(biāo)記的這個(gè)位置。下面是個(gè)例子:

buffer.mark();
//call buffer.get() a couple of times, e.g. during parsing.
buffer.reset(); //set position back to mark.

equals() and compareTo()

用equals() 和 compareTo()方法可以比較兩個(gè)緩沖區(qū)。

equals()

兩個(gè)緩沖相同,如果:

1.他們是同一個(gè)類型(byte,char,int等)。

2.在緩沖區(qū),它們遺留有相同量的字節(jié)、字符等。

3.所有遺留的字節(jié)、字符都相同。

正如你看到的,equals只比較Buffer的一部分,而不是每個(gè)元素。事實(shí)上,它只比較Buffer中遺留的元素。

compareTo()

用 compareTo() 方法比較兩個(gè)緩沖區(qū)的遺留元素(字節(jié)、字符等),用在例如排序例程。在下列情況中,一個(gè)緩沖區(qū)被視為“小于”另一個(gè)緩沖區(qū),如果:

與另一個(gè)緩沖區(qū)對(duì)應(yīng)元素相等的第一個(gè)元素,小于另一個(gè)緩沖區(qū)的元素。

所有的元素都相等,但是第一個(gè)緩沖區(qū)在第二個(gè)緩沖區(qū)之前耗盡了元素(它有更少的元素)。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • springboot返回值轉(zhuǎn)成JSONString的處理方式

    springboot返回值轉(zhuǎn)成JSONString的處理方式

    這篇文章主要介紹了springboot返回值轉(zhuǎn)成JSONString的處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • Java圖形用戶界面設(shè)計(jì)(Swing)的介紹

    Java圖形用戶界面設(shè)計(jì)(Swing)的介紹

    看到多數(shù)人提到 Java 就以為是網(wǎng)絡(luò)開發(fā),其實(shí)不是這樣的,Java 也可以開發(fā)應(yīng)用程序,而且可以開發(fā)出漂亮的圖形用戶界面的應(yīng)用程序,因此,我寫下這篇文章,希望能帶你進(jìn)入 Java 圖形用戶界面設(shè)計(jì)之門。
    2016-07-07
  • java.io.File的renameTo方法移動(dòng)文件失敗的解決方案

    java.io.File的renameTo方法移動(dòng)文件失敗的解決方案

    這篇文章主要介紹了java.io.File的renameTo方法移動(dòng)文件失敗的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • 詳談java線程與線程、進(jìn)程與進(jìn)程間通信

    詳談java線程與線程、進(jìn)程與進(jìn)程間通信

    下面小編就為大家?guī)硪黄斦刯ava線程與線程、進(jìn)程與進(jìn)程間通信。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-04-04
  • java中DES加密解密

    java中DES加密解密

    本文給大家分享的是一段java中實(shí)現(xiàn)des加密解密的代碼,非常的實(shí)用,基本每個(gè)項(xiàng)目都可以用到,推薦給大家。
    2015-03-03
  • SpringBoot項(xiàng)目中接口防刷的完整代碼

    SpringBoot項(xiàng)目中接口防刷的完整代碼

    本文通過實(shí)例代碼給大家介紹了SpringBoot項(xiàng)目中接口防刷的方法,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2021-07-07
  • java設(shè)計(jì)模式學(xué)習(xí)之工廠方法模式

    java設(shè)計(jì)模式學(xué)習(xí)之工廠方法模式

    這篇文章主要介紹了java設(shè)計(jì)模式學(xué)習(xí)之工廠方法模式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • SpringBoot 整合 Shiro 密碼登錄的實(shí)現(xiàn)代碼

    SpringBoot 整合 Shiro 密碼登錄的實(shí)現(xiàn)代碼

    這篇文章主要介紹了SpringBoot 整合 Shiro 密碼登錄的實(shí)現(xiàn),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-02-02
  • springboot集成測(cè)試容器重啟問題的處理

    springboot集成測(cè)試容器重啟問題的處理

    這篇文章主要介紹了springboot集成測(cè)試容器重啟問題的處理,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • 關(guān)于Eureka的概念作用以及用法詳解

    關(guān)于Eureka的概念作用以及用法詳解

    這篇文章主要介紹了關(guān)于Eureka的概念作用以及用法詳解,服務(wù)治理就是提供了微服務(wù)架構(gòu)中各微服務(wù)實(shí)例的快速上線或下線且保持各服務(wù)能正常通信的能力的方案總稱,需要的朋友可以參考下
    2023-05-05

最新評(píng)論