乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Java中的緩沖區(qū)

       ytkomn 2011-09-20
      如果將同步I/O方式下的數(shù)據(jù)傳輸比做數(shù)據(jù)傳輸?shù)牧阈欠绞?這里的零星是指在數(shù)據(jù)傳輸?shù)倪^程中是以零星的字節(jié)方式進行的),那么就可以將非阻塞 I/O方式下的數(shù)據(jù)傳輸比做數(shù)據(jù)傳輸?shù)募b箱方式(在字節(jié)和低層數(shù)據(jù)傳輸之間,多了一層緩沖區(qū),因此,可以將緩沖區(qū)看做是裝載字節(jié)的集裝箱)。大家可以想 象,如果我們要運送比較少的貨物,用集裝箱好象有點不太合算,而如果要運送上百噸的貨物,用集裝箱來運送的成本會更低。在數(shù)據(jù)傳輸過程中也是一樣,如果數(shù) 據(jù)量很小時,使用同步I/O方式會更適合,如果數(shù)據(jù)量很大時(一般以G為單位),使用非阻塞I/O方式的效率會更高。因此,從理論上說,數(shù)據(jù)量越大,使用非阻塞I/O方式的單位成本就會越低。產(chǎn)生這種結果的原因和緩沖區(qū)的一些特性有著直接的關系。在本節(jié)中,將對緩沖區(qū)的一些主要特性進行講解,使讀者可以充分理解緩沖區(qū)的概念,并能通過緩沖區(qū)來提高程序的執(zhí)行效率

        創(chuàng)建緩沖區(qū)

        Java提供了七個基本的緩沖區(qū),分別由七個類來管理,它們都可以在java.nio包中找到。這七個類如下所示:

       


      ByteBuffer
      ShortBuffer
      IntBuffer
      CharBuffer
      FloatBuffer
      DoubleBuffer
      LongBuffer
      st1":*{behavior:url(#ieooui) }

        這七個類中的方法類似,只是它們的返回值或參數(shù)和相應的簡單類型相對應,如ByteBuffer類的get方法返回了byte類型的數(shù)據(jù),而 put方法需要一個byte類型的參數(shù)。在CharBuffer類中的get和put方法返回和傳遞的數(shù)據(jù)類型就是char。這七個類都沒有public 構造方法,因此,它們不能通過new來創(chuàng)建相應的對象實例。這些類都可以通過兩種方式來創(chuàng)建相應的對象實例。

        1. 通過靜態(tài)方法allocate來創(chuàng)建緩沖區(qū)。

        這七類都有一個靜態(tài)的allocate方法,通過這個方法可以創(chuàng)建有最大容量限制的緩沖區(qū)對象。allocate的定義如下:

        ByteBuffer類中的allocate方法:

       


      public static ByteBuffer allocate(int capacity)

        IntBuffer類中的allocate方法:

       


      public static IntBuffer allocate(int capacity)

        其他五個緩沖區(qū)類中的allocate 方法定義和上面的定義類似,只是返回值的類型是相應的緩沖區(qū)類。

        allocate方法有一個參數(shù)capacity,用來指定緩沖區(qū)容量的最大值。capacity的不能小于0,否則會拋出一個 IllegalArgumentException異常。使用allocate來創(chuàng)建緩沖區(qū),并不是一下子就分配給緩沖區(qū)capacity大小的空間,而 是根據(jù)緩沖區(qū)中存儲數(shù)據(jù)的情況來動態(tài)分配緩沖區(qū)的大小(實際上,在低層Java采用了數(shù)據(jù)結構中的堆來管理緩沖區(qū)的大小),因此,這個capacity可 以是一個很大的值,如1024*1024(1M)。allocate的使用方法如下:

       


      ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
      IntBuffer intBuffer = IntBuffer.allocate(1024);

        在使用allocate創(chuàng)建緩沖區(qū)時應用注意,capacity的含義隨著緩沖區(qū)的不同而不同。如創(chuàng)建字節(jié)緩沖區(qū)時,capacity指的是字 節(jié)數(shù)。而在創(chuàng)建整型(int)緩沖區(qū)時,capacity指的是int型值的數(shù)目,如果轉換成字數(shù),capacity的值應該乘4。如上面代碼中的 intBuffer緩沖區(qū)最大可容納的字節(jié)數(shù)是1024*4 = 4096個。

        2. 通過靜態(tài)方法wrap來創(chuàng)建緩沖區(qū)。

        使用allocate方法可以創(chuàng)建一個空的緩沖區(qū)。而wrap方法可以利用已經(jīng)存在的數(shù)據(jù)來創(chuàng)建緩沖區(qū)。wrap方法可以將數(shù)組直接轉換成相應類型的緩沖區(qū)。wrap方法有兩種重載形式,它們的定義如下:

        ByteBuffer類中的wrap方法:

       


      public static ByteBuffer wrap(byte[] array)
      public static ByteBuffer wrap(byte[] array, int offset, int length)

        IntBuffer類中的wrap方法:

       


      public static IntBuffer wrap(byte[] array)
      public static IntBuffer wrap(byte[] array, int offset, int length)

        其他五個緩沖區(qū)類中的wrap 方法定義和上面的定義類似,只是返回值的類型是相應的緩沖區(qū)類。

        在wrap方法中的array參數(shù)是要轉換的數(shù)組(如果是其他的緩沖區(qū)類,數(shù)組的類型就是相應的簡單類型,如IntBuffer類中的wrap 方法的array就是int[]類型)。offset是要轉換的子數(shù)組的偏移量,也就是子數(shù)組在array中的開始索引。length是要轉換的子數(shù)組的 長度。利用后兩個參數(shù)可以將array數(shù)組中的一部分轉換成緩沖區(qū)對象。它們的使用方法如下:

       


      byte[] myByte = new byte[] { 1, 2, 3 };
      int[] myInt = new int[] { 1, 2, 3, 4 };
      ByteBuffer byteBuffer = ByteBuffer.wrap(myByte);
      IntBuffer intBuffer = IntBuffer.wrap(myInt, 1, 2);

        可以通過緩沖區(qū)類的capacity方法來得到緩沖區(qū)的大小。capacity方法的定義如下:

       


      public final int capacity()

        如果使用allocate方法來創(chuàng)建緩沖區(qū),capacity方法的返回值就是capacity參數(shù)的值。而使用wrap方法來創(chuàng)建緩沖 區(qū),capacity方法的返回值是array數(shù)組的長度,但要注意,使用wrap來轉換array的字數(shù)組時,capacity的長度仍然是原數(shù)組的長 度,如上面代碼中的intBuffer緩沖區(qū)的capacity值是4,而不是2。

        除了可以將數(shù)組轉換成緩沖區(qū)外,也可以通過緩沖區(qū)類的array方法將緩沖區(qū)轉換成相應類型的數(shù)組。IntBuffer類的array方法的定義方法如下(其他緩沖區(qū)類的array的定義類似):

       


      public final int[] array()

        下面的代碼演示了如何使用array方法將緩沖區(qū)轉換成相應類型的數(shù)組。

       


      int[] myInt = new int[] { 1, 2, 3, 4, 5, 6 };
      IntBuffer intBuffer = IntBuffer.wrap(myInt, 1, 3);
      for (int v : intBuffer.array())
      System.out.print(v + " ");

        在執(zhí)行上面代碼后,我們發(fā)現(xiàn)輸出的結果是1 2 3 4 5 6,而不是2 3 4。這說明在將子數(shù)組轉換成緩沖區(qū)的過程中實際上是將整個數(shù)組轉換成了緩沖區(qū),這就是用wrap包裝子數(shù)組后,capacity的值仍然是原數(shù)組長度的真 正原因。在使用array方法時應注意,在以下兩種緩沖區(qū)中不能使用array方法:

        只讀的緩沖區(qū)

        如果使用只讀緩沖區(qū)的array方法,將會拋出一個ReadOnlyBufferException異常。

        使用allocateDirect方法創(chuàng)建的緩沖區(qū)。

        如果調用這種緩沖區(qū)中的array方法,將會拋出一個UnsupportedOperationException異常。

        可以通過緩沖區(qū)類的hasArray方法來判斷這個緩沖區(qū)是否可以使用array方法,如果返回true,則說明這個緩沖區(qū)可以使用array方法,否則,使用array方法將會拋出上述的兩種異常之一。

        注意: 使用array方法返回的數(shù)組并不是緩沖區(qū)數(shù)據(jù)的副本。被返回的數(shù)組實際上就是緩沖區(qū)中的數(shù)據(jù),也就是說,array方法只返回了緩沖區(qū)數(shù)據(jù)的引用。當數(shù) 組中的數(shù)據(jù)被修改后,緩沖區(qū)中的數(shù)據(jù)也會被修改,返之也是如此。關于這方面內(nèi)容將在下一節(jié)“讀寫緩沖區(qū)中的數(shù)據(jù)”中詳細講解。

        在上述的七個緩沖區(qū)類中,ByteBuffer類和CharBuffer類各自還有另外一種方法來創(chuàng)建緩沖區(qū)對象。

        l ByteBuffer類

        可以通過ByteBuffer類的allocateDirect方法來創(chuàng)建ByteBuffer對象。allocateDirect方法的定義如下:

       


      public static ByteBuffer allocateDirect(int capacity)

        使用allocateDirect方法可以一次性分配capacity大小的連續(xù)字節(jié)空間。通過allocateDirect方法來創(chuàng)建具有連續(xù)空間的ByteBuffer對象雖然可以在一定程度上提高效率,但這種方式并不是平臺獨立的。也就是說,在一些操作系統(tǒng)平臺上使用allocateDirect方法來創(chuàng)建ByteBuffer對象會使效率大幅度提高,而在另一些操作系統(tǒng)平臺上,性能會表現(xiàn)得非常差。而且allocateDirect方法需要較長的時間來分配內(nèi)存空間,在釋放空間時也較慢。因此,在使用allocateDirect方法時應謹慎。

        通過isDirect方法可以判斷緩沖區(qū)對象(其他的緩沖區(qū)類也有isDirect方法,因為,ByteBuffer對象可以轉換成其他的緩沖區(qū)對象,這部分內(nèi)容將在后面講解)是用哪種方式創(chuàng)建的,如果isDirect方法返回true,則這個緩沖區(qū)對象是用allocateDirect方法創(chuàng)建的,否則,就是用其他方法創(chuàng)建的緩沖區(qū)對象。

        l CharBuffer類

        我們可以發(fā)現(xiàn),上述的七種緩沖區(qū)中并沒有字符串緩沖區(qū),而字符串在程序中卻是最常用的一種數(shù)據(jù)類型。不過不要擔心,雖然java.nio包中并 未提供字符串緩沖區(qū),但卻可以將字符串轉換成字符緩沖區(qū)(就是CharBuffer對象)。在CharBuffer類中的wrap方法除了上述的兩種重載 形式外,又多了兩種重載形式,它們的定義如下:

       


      public static CharBuffer wrap(CharSequence csq)
      public static CharBuffer wrap(CharSequence csq, int start, int end)

        其中csq參數(shù)表示要轉換的字符串,但我們注意到csq的類型并不是String,而是CharSequence。CharSequence類 Java中四個可以表示字符串的類的父類,這四個類是String、StringBuffer、StringBuilder和CharBuffer(大家 要注意,StringBuffer和本節(jié)講的緩沖區(qū)類一點關系都沒有,這個類在java.lang包中)。也就是說,CharBuffer類的wrap方 法可以將這四個類的對象轉換成CharBuffer對象。

        另外兩個參數(shù)start和end分別是子字符串的開始索引和結束索引的下一個位置,如將字符串"1234"中的"23" 轉換成CharBuffer對象的語句如下:

       


      CharBuffer cb = CharBuffer.wrap("1234", 1, 3);

        下面的代碼演示了如何使用wrap方法將不同形式的字符串轉換成CharBuffer對象。

       


      StringBuffer stringBuffer = new StringBuffer("通過StringBuffer創(chuàng)建CharBuffer對象");
      StringBuilder stringBuilder = new StringBuilder("通過StringBuilder創(chuàng)建CharBuffer對象");
      CharBuffer charBuffer1 = CharBuffer.wrap("通過String創(chuàng)建CharBuffer對象");
      CharBuffer charBuffer2 = CharBuffer.wrap(stringBuffer);
      CharBuffer charBuffer3 = CharBuffer.wrap(stringBuilder);
      CharBuffer charBuffer4 = CharBuffer.wrap(charBuffer1, 1, 3);

        本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
        轉藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多