好热闹

好热闹

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 方法
加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。