好热闹

好热闹

bbbbb

三、ByteBuffer詳解

1. ByteBuffer 的設計是抽象類#

主要的實現類有:

HeapByteBuffer 堆 ByteBuffer 用的是 JVM 內的堆內存 --> 讀寫操作效率低 會受到 GC 的影響
2. MapperByteBuffer(抽象類 ,它還有個實現類叫 DirectByBuffer) 使用 OS 內存 ---> 讀寫操作效率高 不受 GC 影響。但是如果不主動析構的話,容易造成內陸泄漏

獲取方式#

Bytebuffer.allocate (10); // 一旦分配空間,不可以動態調整
encode()

核心結構#

ByteBuffer 是一個類似數組的結構,整個結構中包含三個主要的狀態

  1. Capacity
    buffer 的容量,類似於數組的 size
  2. Position
    buffer 當前緩存的下標,在讀取操作時記錄讀到了那個位置,在寫操作時記錄寫到了那個位置。從 0 開始,每讀取一次,下標 + 1
  3. Limit
    讀寫限制,在讀操作時,設置了你能讀多少字節的數據,在寫操作時,設置了你
    還能寫多少字節的數據
    所謂的讀寫模式,本質上就是這幾個狀態的變化。主要有 Position 和 Limit 聯合決定了 Buffer 的讀寫數據區域。

** 下面用圖和代碼的形式來表達 capacity、limit 、position 的狀態改變 **

image

@Test
    public void test1(){

        ByteBuffer buffer = ByteBuffer.allocate(10);

        // 新創建的buffer 的狀態
        System.out.println("buffer.capacity() = " + buffer.capacity()); // 10
        System.out.println("buffer.position() = " + buffer.position()); // 0
        System.out.println("buffer.limit() = " + buffer.limit()); // 10

    }

image

@Test
    public void test2(){

        ByteBuffer buffer = ByteBuffer.allocate(10);

        // 存幾個數據,然後再看狀態
        buffer.put(new byte[]{'a','b','c','d'});


        System.out.println("buffer.capacity() = " + buffer.capacity()); // 10
        System.out.println("buffer.position() = " + buffer.position()); // 4
        System.out.println("buffer.limit() = " + buffer.limit()); // 10

    }

image

@Test
    public void test3(){

        ByteBuffer buffer = ByteBuffer.allocate(10);

        // 存幾個數據
        buffer.put(new byte[]{'a','b','c','d'});

        // 切換為讀模式,再看狀態
        buffer.flip();

        System.out.println("buffer.capacity() = " + buffer.capacity()); // 10
        System.out.println("buffer.position() = " + buffer.position()); // 0
        System.out.println("buffer.limit() = " + buffer.limit()); // 4

    }

image

@Test
    public void test4(){

        ByteBuffer buffer = ByteBuffer.allocate(10);

        // 存幾個數據
        buffer.put(new byte[]{'a','b','c','d'});

        // 切換為寫模式,再看狀態
        buffer.clear();

        System.out.println("buffer.capacity() = " + buffer.capacity()); // 10
        System.out.println("buffer.position() = " + buffer.position()); // 0
        System.out.println("buffer.limit() = " + buffer.limit()); // 10

    }

image

@Test
    public void test5(){

        ByteBuffer buffer = ByteBuffer.allocate(10);

        // 存幾個數據
        buffer.put(new byte[]{'a','b','c','d'});

        // 讀取2個數據
        buffer.flip();
        byte b = buffer.get();
        byte b2 = buffer.get();

        System.out.println("buffer.capacity() = " + buffer.capacity()); // 10
        System.out.println("buffer.position() = " + buffer.position()); // 2
        System.out.println("buffer.limit() = " + buffer.limit()); // 4


        // 用compact來切換寫模式,再看狀態
        buffer.compact();


        System.out.println("buffer.capacity() = " + buffer.capacity()); // 10
        System.out.println("buffer.position() = " + buffer.position()); // 2
        System.out.println("buffer.limit() = " + buffer.limit()); // 10
        /* 結果
        *   buffer.capacity() = 10
            buffer.position() = 2
            buffer.limit() = 4
            buffer.capacity() = 10
            buffer.position() = 2
            buffer.limit() = 10
        * */
    }

最後總結一下#

寫入 Buffer 數據之前要設置寫模式

  1. 寫模式
  2. 新創建的 Buffer 自動是寫模式
  3. 調用了 clear,compact 方法

讀取 Buffer 數據之前要設置讀模式
2. 讀模式

  1. 調用 flip 方法
載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。