Java NIO流 -- 緩沖區(Buffer,ByteBuffer)


  用來定義緩沖區的所有類都以Buffer類為基類,Buffer定義了緩沖區的基本特征。

  直接子類:

  • ByteBuffer 用來存儲byte類型的緩沖區,可以在這種緩沖區中存儲任意其他基本類型的二進制值(boolean 除外)。存儲的每個二進制值在緩沖區中占據的字節長度根據類型的長度決定,char和short占2個字節,int占4個字節;

  • CharBuffer 只存儲char類型的值的緩沖區;

  • DoubleBuffer 只存儲double類型的值的緩沖區;

  • FloatBuffer 只存儲float類型的值的緩沖區;

  • IntBuffer 只存儲int類型的值的緩沖區;

  • LongBuffer 只存儲long類型的值的緩沖區;

  • ShortBuffer 只存儲short類型的值的緩沖區。

  小結:沒有boolean類型的緩沖區,boolean可以用int代替。

1、緩沖區容量

  緩沖區容量是指緩沖區所能包含的值的最大數目而不是字節數目(除非存儲byte類型的元素,byte占一個字節)。緩沖區的容量一旦創建不能改變。通過調用capacity()方法返回緩沖區容量。

2、緩沖區的limit和position

3、創建緩沖區

  緩沖區類沒有公共的構造函數,可以用靜態工廠的方法創建。可以調用靜態方法allocate()方法創建ByteBuffer緩沖區對象。

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

  第一行創建一個容量為1024,position為0。

  第二行創建了一個容量為100,limit為100,占據了400個字節的(因為每個int4個字節),position為0的緩沖區。 

  實踐得知除了ByteBuffer之外的緩沖區無法進行IO操作。通常創建ByteBuffer,在通過ByteBuffer創建其他的緩沖區。

a、創建視圖緩沖區

  可以用ByteBuffer對象創建其他類型的緩沖區,新緩沖區共享原始ByteBuffer的全部或者部分內存,這樣的緩沖區被叫做視圖緩沖區。

  視圖緩沖區有兩種用途:

  • 在非byte類型的數據項被寫入到文件中之前把他們加載到ByteBuffer中;
  • 在從文件中讀取的數據作為非byte類型的數據的值進行訪問。

  創建IntBuffer類型的視圖緩沖區

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

  intBuffer的最大容量為1024/4 (int為4個字節),position為0。

b、復制和切分緩沖區

  調用duplicate()方法復制緩沖區,這個方法返回和原始緩沖區一樣類型的緩沖區,並且共享原始緩沖區的內存,但是容量和limit是單獨分開的。

  調用slice()切分緩沖區,生成的緩沖區被映射到原始緩沖區的一部分,從location到limit-1。同樣內存共享,但是容量和limit是單獨分開的。

c、通過封裝數組來創建緩沖區

  通過warp()方法來創建緩沖區。

String string = "young ken 的技術博客";
byte[] bytes = string.getBytes();
ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);

  這里的bytes和緩沖區用的是一塊內存,如果修改緩沖區的數據數組的數據也發生變化。

4、標記緩沖區

  通過mark()方法進行標記,如對緩沖區進行和一系列設置如

 ByteBuffer byteBuffer = ByteBuffer.allocate(100);
 byteBuffer.limit(50);
 byteBuffer.position(2);
 byteBuffer.mark();

  現在對緩沖區進行了標記,標記的狀態為limit50,position2。我現在要設置position為5,操作完之后調用reset(),緩沖區將重新變成limit50,position2。

5、緩沖區數據傳輸

  在將緩沖區的數據寫入文件之前必須將數據加載到緩沖區。將數據加載到緩沖區的方法是put(),可以用get()方法取到數據。

  put和get有相對和絕對之分,如果是相對操作那么緩沖區的position會發生變化,如果是絕對position就是當前position。

a、傳輸數據到緩沖區

  • put(byte b)  將制定的byte存入到緩沖區中,position+1;
  • put(int index, byte b)  將byte傳輸到緩沖區指定索引位置。position不變;
  • put(byte[] array)  將array數組傳輸到緩沖區當前的position中,position+數組的長度;
  • put(byte[] array, int offset, int length)  將數組的array[offset]到array[length-1]添加到緩沖區中,position+數組的長度;
  • put(ByteBuffer src)  將src保留的字節傳輸到緩沖區中,包括緩沖區src中從當前索引位置limit-1位置的元素。

b、從緩沖區中提取數據

  • get() 從緩沖區中返回當前position的值,position+1;
  • get(int index) 返回索引index的字節;
  • get(byte[] bytes) 從緩沖區位置0開始,提取bytes.length長度的字節。position+bytes.length;
  • get(byte[] bytes, int offset, int length) 從當前緩沖區的position開始,提取length的字節從offset開始。position+length。

 6、flip()和clear()

  • 現在我們要將數據寫到輸出通道中。在這之前,我們必須調用 flip() 方法。這個方法做兩件非常重要的事,它將 limit 設置為當前 position,將 position 設置為 0;

  • clear() 方法。這個方法重設緩沖區以便接收更多的字節。 Clear 做兩種非常重要的事情,它將 limit 設置為與 capacity 相同,它設置 position 為 0。

 

 

 作者   Young-Ken(微博)

                                                  審閱者 Cindy-Leee(微博)

轉載請注明 http://www.cnblogs.com/youngKen/p/4923635.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM