Java NIO使用及原理分析(二)

來源:互聯網
上載者:User

在第一篇中,我們介紹了NIO中的兩個核心對象:緩衝區和通道,在談到緩衝區時,我們說緩衝區對象本質上是一個數組,但它其實是一個特殊的數組,緩衝區對象內建了一些機制,能夠跟蹤和記錄緩衝區的狀態變化情況,如果我們使用get()方法從緩衝區擷取資料或者使用put()方法把資料寫入緩衝區,都會引起緩衝區狀態的變化。本文為NIO使用及原理分析的第二篇,將會分析NIO中的Buffer對象。

在緩衝區中,最重要的屬性有下面三個,它們一起合作完成對緩衝區內部狀態的變化跟蹤:

position:指定了下一個將要被寫入或者讀取的元素索引,它的值由get()/put()方法自動更新,在新建立一個Buffer對象時,position被初始化為0。

limit:指定還有多少資料需要取出(在從緩衝區寫入通道時),或者還有多少空間可以放入資料(在從通道讀入緩衝區時)。

capacity:指定了可以儲存在緩衝區中的最大資料容量,實際上,它指定了底層數組的大小,或者至少是指定了准許我們使用的底層數組的容量。

以上四個屬性值之間有一些相對大小的關係:0 <= position <= limit <= capacity。如果我們建立一個新的容量大小為10的ByteBuffer對象,在初始化的時候,position設定為0,limit和 capacity被設定為10,在以後使用ByteBuffer對象過程中,capacity的值不會再發生變化,而其它兩個個將會隨著使用而變化。四個屬性值分別:

現在我們可以從通道中讀取一些資料到緩衝區中,注意從通道讀取資料,相當於往緩衝區中寫入資料。如果讀取4個自己的資料,則此時position的值為4,即下一個將要被寫入的位元組索引為4,而limit仍然是10,如所示:

下一步把讀取的資料寫入到輸出通道中,相當於從緩衝區中讀取資料,在此之前,必須調用flip()方法,該方法將會完成兩件事情:

1. 把limit設定為當前的position值 
2. 把position設定為0

由於position被設定為0,所以可以保證在下一步輸出時讀取到的是緩衝區中的第一個位元組,而limit被設定為當前的position,可以保證讀取的資料正好是之前寫入到緩衝區中的資料,如所示:

現在調用get()方法從緩衝區中讀取資料寫入到輸出通道,這會導致position的增加而limit保持不變,但position不會超過limit的值,所以在讀取我們之前寫入到緩衝區中的4個自己之後,position和limit的值都為4,如所示:

在從緩衝區中讀取資料完畢後,limit的值仍然保持在我們調用flip()方法時的值,調用clear()方法能夠把所有的狀態變化設定為初始化時的值,如所示:

最後我們用一段代碼來驗證這個過程,如下所示:

[java] view plaincopyprint?
  1. import java.io.*;  
  2. import java.nio.*;  
  3. import java.nio.channels.*;  
  4.   
  5. public class Program {  
  6.     public static void main(String args[]) throws Exception {  
  7.         FileInputStream fin = new FileInputStream("d:\\test.txt");  
  8.         FileChannel fc = fin.getChannel();  
  9.   
  10.         ByteBuffer buffer = ByteBuffer.allocate(10);  
  11.         output("初始化", buffer);  
  12.   
  13.         fc.read(buffer);  
  14.         output("調用read()", buffer);  
  15.   
  16.         buffer.flip();  
  17.         output("調用flip()", buffer);  
  18.   
  19.         while (buffer.remaining() > 0) {  
  20.             byte b = buffer.get();  
  21.             // System.out.print(((char)b));  
  22.         }  
  23.         output("調用get()", buffer);  
  24.   
  25.         buffer.clear();  
  26.         output("調用clear()", buffer);  
  27.   
  28.         fin.close();  
  29.     }  
  30.   
  31.     public static void output(String step, Buffer buffer) {  
  32.         System.out.println(step + " : ");  
  33.         System.out.print("capacity: " + buffer.capacity() + ", ");  
  34.         System.out.print("position: " + buffer.position() + ", ");  
  35.         System.out.println("limit: " + buffer.limit());  
  36.         System.out.println();  
  37.     }  
  38. }  

完成的輸出結果為:

這與我們上面示範的過程一致。在後面的文章中,我們繼續介紹NIO中關於緩衝區一些更進階的使用。

(未完待續)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.