Java NIO 學習筆記 – ByteBuffer

來源:互聯網
上載者:User

在 NIO 庫中,所有資料都是用緩衝區處理的。在讀取資料時,它是直接讀到緩衝區中的。在寫入資料時,它是寫入到緩衝區中的。任何時候訪問 NIO 中的資料,都是將它放到緩衝區中。緩衝區實質上是一個數組。通常它是一個位元組數組,但是也可以使用其他種類的數組。但是一個緩衝區不僅僅是一個數組。緩衝區提供了對資料的結構化訪問,而且還可以跟蹤系統的讀/寫進程。

buffer其實只是一個美化了的數組。

狀態變數

跟蹤資料的狀態情況使buffer可以自己管理資料資源

position: 其實是指從buffer讀取或寫入buffer的下一個元素位置。比如,已經寫入buffer 3個元素那那麼position就是指向第4個位置,即position設定為3(數組從0開始計)。

limit:還有多少資料需要從buffer中取出,或還有多少空間可以放入。postition總是<=limit。

capacity: 表示buffer本身底層數組的容量。limit絕不能>capacity。

filp():作了兩件事情:1.將limit指向現在position的位置 2.將position設定為0 (limit=position;position=0)

    這個過程可以使之前buffer寫入資料時改變的狀態變為可以“準備讀取”。因為之前寫到buffer中的資料就是position 到 limit-1 兩個位置之間(limit指向最後一個資料的後一個位置)。

clear():

也作了兩件事:1. limit=capacity 2.position=0

這個過程可以使buffer讀取資料時改變的狀態改變為“清空並準備寫入”。

存取方法

以下都以bytebuffer為例

get():

   前三個get方法是相對讀取。就是相對於位置狀態來讀取資料,並且會改變position位置狀態。

   byte get();

   ByteBuffer get(byte dst[]);//讀取bytebuffer中資料寫入 dst[]

   ByteBuffer get(byte dst[],int offset, int length);

   該讀取資料是絕對讀取(一個byte),即會忽略limit和position值。並完全繞過了緩衝區的狀態統計方法。

   就是說不會改變buffer內部的位置狀態。

   byte get(int index);

put();

   與get類似 前四個put方法是相對讀取。即受position 以及limit影響,並且會改變 position。

   ByteBuffer put( byte b );

   ByteBuffer put( byte src[] ); //從src[]寫入bytebuffer

   ByteBuffer put( byte src[], int offset, int length );

   ByteBuffer put( ByteBuffer src );

   最後一個是絕對寫入 不會影響position等位置狀態。

   ByteBuffer put( int index, byte b );

除了byte的讀寫還有其他類型的讀寫方法。並且他們都存在相對以及絕對兩類。

操作的典型使用:

view plaincopy to clipboardprint?

  1. while (true) {  
  2.      buffer.clear(); // 準備將資料寫入buffer
  3. int r = fcin.read( buffer ); // channel讀取外部系統的資料並寫入 buffer
  4. if (r==-1) {  
  5. break;  
  6.      }  
  7.      buffer.flip(); //準備將資料讀出buffer
  8.      fcout.write( buffer ); // channel讀取buffer的資料並寫到相應的外部系統
進階應用程式緩衝區的分配和封裝

ByteBuffer.allocate(int);方法可以分配(建立)一個byte類型的buffer。

ByteBuffer.wrap(byte[]);方法可以將一個已有的byte數組封裝出一個新的bytebuffer對象。

後一種方式需要小心處理原來的那個byte數組。因為它可以直接存取了。

緩衝區的分區

分區就是建立“子緩衝區”。子緩衝區共用父緩衝區的一部分底層數組位置。

在某種意義上,子緩衝區就像原來的緩衝區中的一個視窗。

這樣當改變子緩衝區的內容時,父緩衝區的相應位置也會被改變。

分區操作是根據當前position以及limit的值來確定的。

buffer.position( 3 );

buffer.limit( 7 );

ByteBuffer slice = buffer.slice();

唯讀緩衝區

asReadOnlyBuffer()方法可以返回一個與原buffer對象一樣的對象,只是新的buffer對象是唯讀。

直接緩衝區

sun的定義:給定一個直接位元組緩衝區,JAVA 虛擬機器將盡最大努力直接對它執行本機 I/O 操作。也就是說,它會在每一次調用底層作業系統的本機 I/O 操作之前(或之後),嘗試避免將緩衝區的內容拷貝到一個中間緩衝區中(或者從一個中間緩衝區中拷貝資料)。

建立directbuffer的方式是用ByteBuffer.allocateDirect( int );方法替代ByteBuffer.allocate(int);

記憶體影射檔案I/O

它讀寫要比其他IO快很多.

他使檔案或檔案的一部分由記憶體影射。但是只有操作該部分位置的資料才是以記憶體方式讀寫的,而不是整個檔案讀入記憶體。(並且他是一個os的底層機制。由os底層非同步完成記憶體與物理磁碟上的資料同步)

影射檔案可以通過FileChannel對象的map方法得到。

比如以下就是將一個檔案的前1024個位元組影射到記憶體,並建立一個MappedByteBuffer對象返回出來。MappedByteBuffer是ByteBuffer的一個子類。

MappedByteBuffer mbb = fc.map( FileChannel.MapMode.READ_WRITE, start, size );

參考地址:http://blog.csdn.net/wfeng007/archive/2010/02/14/5308614.aspx

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.