java.nio.ByteBuffer中的flip()、rewind()、compact()等方法的使用和區別


java.nio.ByteBuffer

1. ByteBuffer中的參數position、limit、capacity、mark含義:

position:表示當前指針的位置(下一個要操作的數據元素的位置)

limit:表示當前數組最大的使用量,即有效位置的EOF位置(緩沖區數組中不可操作的下一個元素的位置,limit<=capacity)

capacity:表示緩沖區最大容量(緩沖區數據的總長度)

mark:用於記錄當前position的前一個位置或者默認是-1

2. ByteBuffer中常用方法含義:

reset():把position設置為mark的值,相當於之前做過一個標記,現在回退到之前標記的地方。

clear():將參數設置為position=0,limit=capacity,mark=-1,類似於初始化,但並不影響底層byte數組的內容(注意:clear只是把指針移到位置0,並沒有真正清空數據)。

flip():將參數設置為limit=position,position=0,mark=-1,翻轉,即將未翻轉之前0到position之間的數據放置到翻轉之后的position(即0)到limit之間的這塊區域,翻轉將緩沖區的狀態由存數據變為准備取數據(注意:將當前位置設置為EOF,指針位置指向0)。

rewind():將參數設置為position=0,mark=-1,limit的值不變(注意:指針指向0)。

remaining():return limit - position,即返回limit和position之間的相對位置差。

hasRemaining():return position < limit,即返回是否還有未讀內容。

compact():將position與limit之間的內容移到0與(limit - position)之間的區域,position的值變為limit - position,limit的值變為capacity;如果先將position的設置到limit,再執行compact操作,就相當於clear操作(注意:compact表示壓縮數據,例如當前EOF是6,當前指針指向2即下標0、1位置的數據已經寫出,此時執行compact方法就是將下標2、3、4、5的數據移動到下標0、1、2、3的位置,指針指向下標4的位置,然后從4的位置繼續寫入數據。寫完后,把指針移動到0,再寫出,然后再執行compact操作,如此反復......)。

示例:初始化一個ByteBuffer,緩沖區最大容量為10,開始指針指向下標0即position=0。

   然后寫入6字節數據,寫入完成后下標0、1、2、3、4、5位置有實際寫入的數據,下標6、7、8、9位置為默認值0。

   此時,指針指向6,即position=6,limit(6)方法會將當前位置設為EOF位置。

   最后,讀取數據時讀取到EOF位置就會結束。

示例代碼

 1 import java.nio.ByteBuffer;
 2 
 3 public class ByteBufferTest {
 4 
 5     public static void main(String[] args) {
 6 
 7         //分配10字節大小內存空間
 8         ByteBuffer buffer = ByteBuffer.allocate(10);
 9         //輸出初始化后position的值
10         System.out.println("初始化position : " + buffer.position());
11         //輸出初始化收limit的值
12         System.out.println("初始化limit : " + buffer.limit());
13         //輸出初始化后capacity的值
14         System.out.println("初始化capacity : " + buffer.capacity());
15         //輸出初始化后ByteBuffer內容
16         printBuffer(buffer);
17 
18         //調用rewind()之前指針指向下標9即位置10,已經是最大容量
19         //調用rewind()之后將指針移動到下標0即位置1
20         buffer.rewind();
21         System.out.println("position:" + buffer.position() + ",limit:" + buffer.limit() + ",capacity:" + buffer.capacity());
22         //執行寫入操作,指針會自動移動
23         buffer.putChar('a');
24         //輸出指針position,指針指向下標2即位置3
25         System.out.println("寫入字符'a'后,position位置為:" + buffer.position());
26         buffer.putChar('啊');
27         //輸出指針position,指針指向下標4即位置5
28         System.out.println("寫入字符'啊'后,position位置為:" + buffer.position());
29 
30         //將當前位置設置為EOF,指針移動到下標0即位置1
31         buffer.flip();
32         System.out.println("position:" + buffer.position() + ",limit:" + buffer.limit() + ",capacity:" + buffer.capacity());
33         //上一行代碼相當於下面兩句
34         //buffer.limit(4);
35         //buffer.position(0);
36 
37         //輸出ByteBuffer內容,即0 61 55 4a
38         printBuffer(buffer);
39         //將指針移動到下標1即位置2
40         buffer.position(1);
41         //進行compact壓縮操作,compact操作會將EOF位置重置為最大容量10
42         //注意:該壓縮操作是將下標1即位置2到位置4的值移動到位置1到位置3,位置4上的值4a不變
43         buffer.compact();
44         //輸出ByteBuffer內容,即61 55 4a 4a 0 0 0 0 0 0(注意:未覆蓋到的位置4的值4a不變)
45         printBuffer(buffer);
46 
47         //注意:執行壓縮compact操作后指針指向下標3即位置4,繼續寫入數據時會覆蓋數據
48         System.out.println(buffer.position());
49     }
50 
51     /**
52      * 輸出ByteBuffer內容
53      * @param buffer
54      */
55     public static void printBuffer(ByteBuffer buffer){
56 
57         //記錄當前位置
58         int position = buffer.position();
59         //指針移動到0
60         buffer.position(0);
61         //循環輸出每個字節內容
62         for(int i = 0;i < buffer.limit();i++){
63             //讀取操作,指針會自動移動
64             byte b = buffer.get();
65             System.out.print(Integer.toHexString(b));
66         }
67         //指針再移動到標記位置
68         buffer.position(position);
69         System.out.println();
70     }
71 }

輸出結果

初始化position : 0 初始化limit : 10 初始化capacity : 10
0000000000 position:0,limit:10,capacity:10 寫入字符'a'后,position位置為:2 寫入字符'啊'后,position位置為:4 position:0,limit:4,capacity:10 061554a 61554a4a000000 3

 


免責聲明!

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



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