国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Java NIO 之 Buffer(緩沖區(qū))

gitmilk / 2273人閱讀

摘要:一緩沖區(qū)介紹用于和交互。的容量,位置,上限緩沖區(qū)實質(zhì)上就是一塊內(nèi)存,用于寫入數(shù)據(jù),也供后續(xù)再次讀取數(shù)據(jù)。在每個類中,方法用于分配緩沖區(qū)。沒有這句話會報錯將此緩沖區(qū)的位置重置為先前標(biāo)記的位置。返回此緩沖區(qū)的限制。

一 Buffer(緩沖區(qū))介紹

Java NIO Buffers用于和NIO Channel交互。 我們從Channel中讀取數(shù)據(jù)到buffers里,從Buffer把數(shù)據(jù)寫入到Channels.

Buffer本質(zhì)上就是一塊內(nèi)存區(qū),可以用來寫入數(shù)據(jù),并在稍后讀取出來。這塊內(nèi)存被NIO Buffer包裹起來,對外提供一系列的讀寫方便開發(fā)的接口。

在Java NIO中使用的核心緩沖區(qū)如下(覆蓋了通過I/O發(fā)送的基本數(shù)據(jù)類型:byte, char、short, int, long, float, double ,long):

ByteBuffer

CharBuffer

ShortBuffer

IntBuffer

FloatBuffer

DoubleBuffer

LongBuffer

利用Buffer讀寫數(shù)據(jù),通常遵循四個步驟:

把數(shù)據(jù)寫入buffer;

調(diào)用flip;

從Buffer中讀取數(shù)據(jù);

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

當(dāng)寫入數(shù)據(jù)到buffer中時,buffer會記錄已經(jīng)寫入的數(shù)據(jù)大小。當(dāng)需要讀數(shù)據(jù)時,通過 flip() 方法把buffer從寫模式調(diào)整為讀模式;在讀模式下,可以讀取所有已經(jīng)寫入的數(shù)據(jù)。

當(dāng)讀取完數(shù)據(jù)后,需要清空buffer,以滿足后續(xù)寫入操作。清空buffer有兩種方式:調(diào)用 clear()compact() 方法。clear會清空整個buffer,compact則只清空已讀取的數(shù)據(jù),未被讀取的數(shù)據(jù)會被移動到buffer的開始位置,寫入位置則近跟著未讀數(shù)據(jù)之后。

Buffer的容量,位置,上限(Buffer Capacity, Position and Limit)

Buffer緩沖區(qū)實質(zhì)上就是一塊內(nèi)存,用于寫入數(shù)據(jù),也供后續(xù)再次讀取數(shù)據(jù)。這塊內(nèi)存被NIO Buffer管理,并提供一系列的方法用于更簡單的操作這塊內(nèi)存。

一個Buffer有三個屬性是必須掌握的,分別是:

capacity容量

position位置

limit限制

position和limit的具體含義取決于當(dāng)前buffer的模式。capacity在兩種模式下都表示容量。

下面有張示例圖,描訴了讀寫模式下position和limit的含義:

容量(Capacity)

作為一塊內(nèi)存,buffer有一個固定的大小,叫做capacit(容量)。也就是最多只能寫入容量值得字節(jié),整形等數(shù)據(jù)。一旦buffer寫滿了就需要清空已讀數(shù)據(jù)以便下次繼續(xù)寫入新的數(shù)據(jù)。

位置(Position)

當(dāng)寫入數(shù)據(jù)到Buffer的時候需要從一個確定的位置開始,默認(rèn)初始化時這個位置position為0,一旦寫入了數(shù)據(jù)比如一個字節(jié),整形數(shù)據(jù),那么position的值就會指向數(shù)據(jù)之后的一個單元,position最大可以到capacity-1.

當(dāng)從Buffer讀取數(shù)據(jù)時,也需要從一個確定的位置開始。buffer從寫入模式變?yōu)樽x取模式時,position會歸零,每次讀取后,position向后移動。

上限(Limit)

在寫模式,limit的含義是我們所能寫入的最大數(shù)據(jù)量,它等同于buffer的容量。

一旦切換到讀模式,limit則代表我們所能讀取的最大數(shù)據(jù)量,他的值等同于寫模式下position的位置。換句話說,您可以讀取與寫入數(shù)量相同的字節(jié)數(shù)(限制設(shè)置為寫入的字節(jié)數(shù),由位置標(biāo)記)。

二 Buffer的常見方法
方法 介紹
abstract Object array() 返回支持此緩沖區(qū)的數(shù)組 (可選操作)
abstract int arrayOffset() 返回該緩沖區(qū)的緩沖區(qū)的第一個元素的背襯數(shù)組中的偏移量 (可選操作)
int capacity() 返回此緩沖區(qū)的容量
Buffer clear() 清除此緩存區(qū)。將position = 0;limit = capacity;mark = -1;
Buffer flip() flip()方法可以吧Buffer從寫模式切換到讀模式。調(diào)用flip方法會把position歸零,并設(shè)置limit為之前的position的值。 也就是說,現(xiàn)在position代表的是讀取位置,limit標(biāo)示的是已寫入的數(shù)據(jù)位置。
abstract boolean hasArray() 告訴這個緩沖區(qū)是否由可訪問的數(shù)組支持
boolean hasRemaining() return position < limit,返回是否還有未讀內(nèi)容
abstract boolean isDirect() 判斷個緩沖區(qū)是否為 direct
abstract boolean isReadOnly() 判斷告知這個緩沖區(qū)是否是只讀的
int limit() 返回此緩沖區(qū)的限制
Buffer position(int newPosition) 設(shè)置這個緩沖區(qū)的位置
int remaining() return limit - position; 返回limit和position之間相對位置差
Buffer rewind() 把position設(shè)為0,mark設(shè)為-1,不改變limit的值
Buffer mark() 將此緩沖區(qū)的標(biāo)記設(shè)置在其位置
三 Buffer的使用方式/方法介紹
分配緩沖區(qū)(Allocating a Buffer)

為了獲得緩沖區(qū)對象,我們必須首先分配一個緩沖區(qū)。在每個Buffer類中,allocate()方法用于分配緩沖區(qū)。

下面來看看ByteBuffer分配容量為28字節(jié)的例子:

ByteBuffer buf = ByteBuffer.allocate(28);

下面來看看另一個示例:CharBuffer分配空間大小為2048個字符。

CharBuffer buf = CharBuffer.allocate(2048);
寫入數(shù)據(jù)到緩沖區(qū)(Writing Data to a Buffer)

寫數(shù)據(jù)到Buffer有兩種方法:

從Channel中寫數(shù)據(jù)到Buffer

手動寫數(shù)據(jù)到Buffer,調(diào)用put方法

下面是一個實例,演示從Channel寫數(shù)據(jù)到Buffer:

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

通過put寫數(shù)據(jù):

buf.put(127);

put方法有很多不同版本,對應(yīng)不同的寫數(shù)據(jù)方法。例如把數(shù)據(jù)寫到特定的位置,或者把一個字節(jié)數(shù)據(jù)寫入buffer。看考JavaDoc文檔可以查閱的更多數(shù)據(jù)。

翻轉(zhuǎn)(flip())

flip()方法可以吧Buffer從寫模式切換到讀模式。調(diào)用flip方法會把position歸零,并設(shè)置limit為之前的position的值。 也就是說,現(xiàn)在position代表的是讀取位置,limit標(biāo)示的是已寫入的數(shù)據(jù)位置。

從Buffer讀取數(shù)據(jù)(Reading Data from a Buffer)

從Buffer讀數(shù)據(jù)也有兩種方式。

從buffer讀數(shù)據(jù)到channel

從buffer直接讀取數(shù)據(jù),調(diào)用get方法

讀取數(shù)據(jù)到channel的例子:

int bytesWritten = inChannel.write(buf);

調(diào)用get讀取數(shù)據(jù)的例子:

byte aByte = buf.get();

get也有諸多版本,對應(yīng)了不同的讀取方式。

rewind()

Buffer.rewind()方法將position置為0,這樣我們可以重復(fù)讀取buffer中的數(shù)據(jù)。limit保持不變。

clear() and compact()

一旦我們從buffer中讀取完數(shù)據(jù),需要復(fù)用buffer為下次寫數(shù)據(jù)做準(zhǔn)備。只需要調(diào)用clear()或compact()方法。

如果調(diào)用的是clear()方法,position將被設(shè)回0,limit被設(shè)置成 capacity的值。換句話說,Buffer 被清空了。Buffer中的數(shù)據(jù)并未清除,只是這些標(biāo)記告訴我們可以從哪里開始往Buffer里寫數(shù)據(jù)。

如果Buffer還有一些數(shù)據(jù)沒有讀取完,調(diào)用clear就會導(dǎo)致這部分?jǐn)?shù)據(jù)被“遺忘”,因為我們沒有標(biāo)記這部分?jǐn)?shù)據(jù)未讀。

針對這種情況,如果需要保留未讀數(shù)據(jù),那么可以使用compact。 因此 compact()clear() 的區(qū)別就在于: 對未讀數(shù)據(jù)的處理,是保留這部分?jǐn)?shù)據(jù)還是一起清空

mark()與reset()方法

通過調(diào)用Buffer.mark()方法,可以標(biāo)記Buffer中的一個特定position。之后可以通過調(diào)用Buffer.reset()方法恢復(fù)到這個position。例如:

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

可以用eqauls和compareTo比較兩個buffer

equals():

判斷兩個buffer相對,需滿足:

類型相同

buffer中剩余字節(jié)數(shù)相同

所有剩余字節(jié)相等

從上面的三個條件可以看出,equals只比較buffer中的部分內(nèi)容,并不會去比較每一個元素。

compareTo():

compareTo也是比較buffer中的剩余元素,只不過這個方法適用于比較排序的:

四 Buffer常用方法測試

這里以ByteBuffer為例子說明抽象類Buffer的實現(xiàn)類的一些常見方法的使用:

package channel;

import java.nio.ByteBuffer;

public class ByteBufferMethods {
    public static void main(String args[]){
        //分配緩沖區(qū)(Allocating a Buffer)
        ByteBuffer buffer = ByteBuffer.allocate(33);

        System.out.println("-------------Test reset-------------");
        //clear()方法,position將被設(shè)回0,limit被設(shè)置成 capacity的值
        buffer.clear();
       // 設(shè)置這個緩沖區(qū)的位置
        buffer.position(5);
        //將此緩沖區(qū)的標(biāo)記設(shè)置在其位置。沒有buffer.mark();這句話會報錯
        buffer.mark();
        buffer.position(10);
        System.out.println("before reset:      " + buffer);
        //將此緩沖區(qū)的位置重置為先前標(biāo)記的位置。(buffer.position(5))
        buffer.reset();
        System.out.println("after reset:       " + buffer);

        System.out.println("-------------Test rewind-------------");
        buffer.clear();
        buffer.position(10);
        //返回此緩沖區(qū)的限制。
        buffer.limit(15);
        System.out.println("before rewind:       " + buffer);
        //把position設(shè)為0,mark設(shè)為-1,不改變limit的值
        buffer.rewind();
        System.out.println("before rewind:       " + buffer);

        System.out.println("-------------Test compact-------------");
        buffer.clear();
        buffer.put("abcd".getBytes());
        System.out.println("before compact:       " + buffer);
        System.out.println(new String(buffer.array()));
        //limit = position;position = 0;mark = -1; 翻轉(zhuǎn),也就是讓flip之后的position到limit這塊區(qū)域變成之前的0到position這塊,
        //翻轉(zhuǎn)就是將一個處于存數(shù)據(jù)狀態(tài)的緩沖區(qū)變?yōu)橐粋€處于準(zhǔn)備取數(shù)據(jù)的狀態(tài)
        buffer.flip();
        System.out.println("after flip:       " + buffer);
        //get()方法:相對讀,從position位置讀取一個byte,并將position+1,為下次讀寫作準(zhǔn)備
        System.out.println((char) buffer.get());
        System.out.println((char) buffer.get());
        System.out.println((char) buffer.get());
        System.out.println("after three gets:       " + buffer);
        System.out.println("	" + new String(buffer.array()));
        //把從position到limit中的內(nèi)容移到0到limit-position的區(qū)域內(nèi),position和limit的取值也分別變成limit-position、capacity。
        // 如果先將positon設(shè)置到limit,再compact,那么相當(dāng)于clear()
        buffer.compact();
        System.out.println("after compact:       " + buffer);
        System.out.println("	" + new String(buffer.array()));

        System.out.println("-------------Test get-------------");
        buffer = ByteBuffer.allocate(32);
        buffer.put((byte) "a").put((byte) "b").put((byte) "c").put((byte) "d")
                .put((byte) "e").put((byte) "f");
        System.out.println("before flip():       " + buffer);
        // 轉(zhuǎn)換為讀取模式
        buffer.flip();
        System.out.println("before get():       " + buffer);
        System.out.println((char) buffer.get());
        System.out.println("after get():       " + buffer);
        // get(index)不影響position的值
        System.out.println((char) buffer.get(2));
        System.out.println("after get(index):       " + buffer);
        byte[] dst = new byte[10];
        buffer.get(dst, 0, 2);
        System.out.println("after get(dst, 0, 2):       " + buffer);
        System.out.println("	 dst:" + new String(dst));
        System.out.println("buffer now is:       " + buffer);
        System.out.println("	" + new String(buffer.array()));

        System.out.println("-------------Test put-------------");
        ByteBuffer bb = ByteBuffer.allocate(32);
        System.out.println("before put(byte):       " + bb);
        System.out.println("after put(byte):       " + bb.put((byte) "z"));
        System.out.println("	" + bb.put(2, (byte) "c"));
        // put(2,(byte) "c")不改變position的位置
        System.out.println("after put(2,(byte) "c"):       " + bb);
        System.out.println("	" + new String(bb.array()));
        // 這里的buffer是 abcdef[pos=3 lim=6 cap=32]
        bb.put(buffer);
        System.out.println("after put(buffer):       " + bb);
        System.out.println("	" + new String(bb.array()));
    }
}
參考:

官方JDK相關(guān)文檔

谷歌搜索排名第一的Java NIO教程

《Java程序員修煉之道》

ByteBuffer常用方法詳解

Java NIO 易百教程

歡迎關(guān)注我的微信公眾號:"Java面試通關(guān)手冊"(一個有溫度的微信公眾號,期待與你共同進(jìn)步~~~堅持原創(chuàng),分享美文,分享各種Java學(xué)習(xí)資源):

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/69395.html

相關(guān)文章

  • 關(guān)于Java IO與NIO知識都在這里

    摘要:從通道進(jìn)行數(shù)據(jù)寫入創(chuàng)建一個緩沖區(qū),填充數(shù)據(jù),并要求通道寫入數(shù)據(jù)。三之通道主要內(nèi)容通道介紹通常來說中的所有都是從通道開始的。從中選擇選擇器維護(hù)注冊過的通道的集合,并且這種注冊關(guān)系都被封裝在當(dāng)中停止選擇的方法方法和方法。 由于內(nèi)容比較多,我下面放的一部分是我更新在我的微信公眾號上的鏈接,微信排版比較好看,更加利于閱讀。每一篇文章下面我都把文章的主要內(nèi)容給列出來了,便于大家學(xué)習(xí)與回顧。 Ja...

    Riddler 評論0 收藏0
  • Java NIO Channel(通道)

    摘要:通道可以異步讀寫。使用的方法讀取數(shù)據(jù)創(chuàng)建一個讀數(shù)據(jù)緩沖區(qū)對象從通道中讀取數(shù)據(jù)使用的方法寫入數(shù)據(jù)創(chuàng)建一個寫數(shù)據(jù)緩沖區(qū)對象寫入數(shù)據(jù)關(guān)閉完成使用后,您必須關(guān)閉它。五提供了一種被稱為的新功能,也稱為本地矢量。功能是通道提供的并不是。 歷史回顧: Java NIO 概覽 Java NIO 之 Buffer(緩沖區(qū)) 其他高贊文章: 面試中關(guān)于Redis的問題看這篇就夠了 一文輕松搞懂redis集...

    piglei 評論0 收藏0
  • Java IONIO

    摘要:上篇說了最基礎(chǔ)的五種模型,相信大家對相關(guān)的概念應(yīng)該有了一定的了解,這篇文章主要講講基于多路復(fù)用的。 上篇說了最基礎(chǔ)的五種IO模型,相信大家對IO相關(guān)的概念應(yīng)該有了一定的了解,這篇文章主要講講基于多路復(fù)用IO的Java NIO。 背景 Java誕生至今,有好多種IO模型,從最早的Java IO到后來的Java NIO以及最新的Java AIO,每種IO模型都有它自己的特點,詳情請看我的上...

    pingink 評論0 收藏0
  • 動力節(jié)點JavaNIO教程,輕松攻破Java NIO技術(shù)壁壘

    摘要:學(xué)習(xí)和掌握技術(shù)已經(jīng)不是一個攻城獅的加分技能,而是一個必備技能。是雙向的,不僅可以讀取數(shù)據(jù)還能保存數(shù)據(jù),程序不能直接讀寫通道,只與緩沖區(qū)交互為了讓大家不被高并發(fā)與大量連接處理問題所困擾,動力節(jié)點推出了高效處理模型應(yīng)用教程。 大家肯定了解Java IO, 但是對于NIO一般是陌生的,而現(xiàn)在使用到NIO的場景越來越多,很多技術(shù)框...

    ralap 評論0 收藏0
  • Java NIO 概覽

    摘要:線程之間的切換對于操作系統(tǒng)來說是昂貴的。因此,單線程可以監(jiān)視多個通道中的數(shù)據(jù)。當(dāng)方法返回后,線程可以處理這些事件。 一 NIO簡介 Java NIO 是 java 1.4 之后新出的一套IO接口,這里的的新是相對于原有標(biāo)準(zhǔn)的Java IO和Java Networking接口。NIO提供了一種完全不同的操作方式。 NIO中的N可以理解為Non-blocking,不單純是New。 它支持面...

    chemzqm 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<