1. 程式人生 > >2、NIO--緩沖區(Buffer)

2、NIO--緩沖區(Buffer)

不可 split 限制 特定 oca cde 下一個 圖片 all

緩沖區(BUffer)

緩沖區(Buffer:一個用於特定基本數據類
型的容器。由 java.nio 包定義的,所有緩沖區
都是 Buffer 抽象類的子類。

Java NIO 中的 Buffer 主要用於與 NIO 通道進行
交互,數據是從通道讀入緩沖區,從緩沖區寫
入通道中的。

緩沖區:在NIO中負責數據的存取,說白了就是數組用於儲存不同類型的數組

根據數據類型不同(boolean類型除外),提供了相應的類型的緩沖區

? ByteBuffer
? CharBuffer
? ShortBuffer
? IntBuffer
? LongBuffer
? FloatBuffer


? DoubleBuffer

上述Buffer類他們都采用相擬的方法進行管理數據

只是各自管理的數據類不同而已

的都是通過同一個方法獲取Buffer對象:

static XxxBuffer allocate(int capacity) : 創建一個容量為 capacity 的 XxxBuffer 對象

ByteBuffer buf = ByteBuffer.allocate(1024);

  

緩沖區存取數據的兩個核心方法:

1、put():存入數據到緩沖區

技術分享圖片

2、get():獲取緩沖區中的數據

技術分享圖片

緩沖區中的四個核心屬性

public
abstract class java.nio.Buffer { // Field descriptor #20 I static final int SPLITERATOR_CHARACTERISTICS = 16464; // Field descriptor #20 I private int mark; // Field descriptor #20 I private int position; // Field descriptor #20 I private int limit; // Field descriptor #20 I
private int capacity; ...

? 容量 (capacity) :表示 Buffer 最大數據容量,緩沖區容量不能為負,並且創
  建後不能更改。


? 限制 (limit):第一個不應該讀取或寫入的數據的索引,即位於 limit 後的數據
  不可讀寫。緩沖區的限制不能為負,並且不能大於其容量


? 位置 (position):下一個要讀取或寫入的數據的索引。緩沖區的位置不能為
  負,並且不能大於其限制


? 標記 (mark)與重置 (reset):標記是一個索引,通過 Buffer 中的 mark() 方法
  指定 Buffer 中一個特定的 position,之後可以通過調用 reset() 方法恢復到這
  個 position.

標記、位置、限制、容量遵守以下不變式: 0 <= mark <= position <= limit <= capacity

    public static void main(String[] args) {
        
        //1、分配一個指定大小的緩沖區
        ByteBuffer buf = ByteBuffer.allocate(1024);
        
        System.out.println(buf.position());//0
        System.out.println(buf.limit());//1024
        System.out.println(buf.capacity());//1024
        System.out.println(buf.mark());//java.nio.HeapByteBuffer[pos=0 lim=1024 cap=1024]
   }    

技術分享圖片

    public static void main(String[] args) {
        
        //1、分配一個指定大小的緩沖區
        ByteBuffer buf = ByteBuffer.allocate(1024);
        
        System.out.println(buf.position());//0
        System.out.println(buf.limit());//1024
        System.out.println(buf.capacity());//1024
        System.out.println(buf.mark());//java.nio.HeapByteBuffer[pos=0 lim=1024 cap=1024]
        
        //2、利用put()方法進行存儲數據
        String str = "hello nio";
        buf.put(str.getBytes());
        
        System.out.println(buf.position());//9
        System.out.println(buf.limit());//1024
        System.out.println(buf.capacity());//1024
        System.out.println(buf.mark());//java.nio.HeapByteBuffer[pos=9 lim=1024 cap=1024]
    }

技術分享圖片

    public static void main(String[] args) {
        
        //1、分配一個指定大小的緩沖區
        ByteBuffer buf = ByteBuffer.allocate(1024);
        
        System.out.println(buf.position());//0
        System.out.println(buf.limit());//1024
        System.out.println(buf.capacity());//1024
        System.out.println(buf.mark());//java.nio.HeapByteBuffer[pos=0 lim=1024 cap=1024]
        
        //2、利用put()方法進行存儲數據
        String str = "hello nio";//9字節
        buf.put(str.getBytes());
        
        System.out.println(buf.position());//9
        System.out.println(buf.limit());//1024
        System.out.println(buf.capacity());//1024
        System.out.println(buf.mark());//java.nio.HeapByteBuffer[pos=9 lim=1024 cap=1024]
        
        //3、切換讀取數據的模式
        buf.flip();
        System.out.println(buf.position());//0
        System.out.println(buf.limit());//9
        System.out.println(buf.capacity());//1024
        System.out.println(buf.mark());//java.nio.HeapByteBuffer[pos=0 lim=9 cap=1024]
        
        //4、利用get()方法讀取數據
        byte dst [] = new byte[buf.limit()];
        buf.get(dst);
        System.out.println(new String(dst,0,dst.length));//hello nio
        
        System.out.println(buf.position());//9
        System.out.println(buf.limit());//9
        System.out.println(buf.capacity());//1024
        System.out.println(buf.mark());//java.nio.HeapByteBuffer[pos=9 lim=9 cap=1024]
}

技術分享圖片

    public static void main(String[] args) {
        
        //1、分配一個指定大小的緩沖區
        ByteBuffer buf = ByteBuffer.allocate(1024);
        
        System.out.println(buf.position());//0
        System.out.println(buf.limit());//1024
        System.out.println(buf.capacity());//1024
        System.out.println(buf.mark());//java.nio.HeapByteBuffer[pos=0 lim=1024 cap=1024]
        
        //2、利用put()方法進行存儲數據
        String str = "hello nio";
        buf.put(str.getBytes());
        
        System.out.println(buf.position());//9
        System.out.println(buf.limit());//1024
        System.out.println(buf.capacity());//1024
        System.out.println(buf.mark());//java.nio.HeapByteBuffer[pos=9 lim=1024 cap=1024]
        
        //3、切換讀取數據的模式
        buf.flip();
        System.out.println(buf.position());//0
        System.out.println(buf.limit());//9
        System.out.println(buf.capacity());//1024
        System.out.println(buf.mark());//java.nio.HeapByteBuffer[pos=0 lim=9 cap=1024]
        
        //4、利用get()方法讀取數據
        byte dst [] = new byte[buf.limit()];
        buf.get(dst);
        System.out.println(new String(dst,0,dst.length));//hello nio
        
        System.out.println(buf.position());//9
        System.out.println(buf.limit());//9
        System.out.println(buf.capacity());//1024
        System.out.println(buf.mark());//java.nio.HeapByteBuffer[pos=9 lim=9 cap=1024]
        
        //5、rewind()回到讀模式(可重復讀數據)
        buf.rewind();
        System.out.println(buf.position());//0
        System.out.println(buf.limit());//9
        System.out.println(buf.capacity());//1024
        System.out.println(buf.mark());//java.nio.HeapByteBuffer[pos=0 lim=9 cap=1024]
    }

rewind():回到讀模式(可重復讀取數據)

技術分享圖片

繼上述代碼繼續添加代碼:

        //6、清空緩沖區
        buf.clear();
        System.out.println(buf.position());//0
        System.out.println(buf.limit());//1024
        System.out.println(buf.capacity());//1024
        System.out.println(buf.mark());//java.nio.HeapByteBuffer[pos=0 lim=1024 cap=1024]

清空緩沖區之後將會回到初始化狀態

緩沖區的數據依然存在,但是處於“被遺忘的數據”(位置界限等都變了)

技術分享圖片

再次進行添加代碼:

        buf.get(dst);
        System.out.println(new String(dst,0,dst.length));//hello nio

技術分享圖片

關於標記和重置的使用

    @Test
    public void test(){
        ByteBuffer buf = ByteBuffer.allocate(1024);
        
        String str="abcde";
        buf.put(str.getBytes());
        
        //切換到讀取數據模式
        buf.flip();
        
        //讀取數據
        byte dst [] = new byte[buf.limit()];
        buf.get(dst,0,2);
        System.out.println("第一次打印操作");
        System.out.println(buf.position());
        System.out.println(new String(dst,0,2));
        
        //進行標記
        buf.mark();
        
        //再次進行讀取數據
        buf.get(dst,2,2);
        System.out.println("第二次打印操作");
        System.out.println(buf.position());
        System.out.println(new String(dst,2,2));
        
        //恢復到之前的位置
        buf.reset();
        System.out.println("恢復到第一次操作備份的位置");
        System.out.println(buf.position());

    }

技術分享圖片

再次添加新的代碼:

        //判斷緩沖區是否還有剩余數據
        if(buf.hasRemaining()){
            //獲取緩沖區可操作的數據的數量
            System.out.println(buf.remaining());
        }

此前有一個恢復到第一次操作數據的位置

所以此時可以操作的數據剩余量為3

技術分享圖片

圖解緩沖區的基本屬性(position、capacity、limit)

技術分享圖片

緩沖區常常使用的方法

技術分享圖片

2、NIO--緩沖區(Buffer)