netty

Buffer缓冲区

2021-04-14  本文已影响0人  GavinZZW

缓冲区(Buffer):缓冲区本质上是一个可以读写数据的内存块,可以理解成是一个数组,该对象
提供了一组方法,可以更轻松地使用内存块,,缓冲区对象内置了一些机制,能够跟踪和记录缓冲区的
状态变化情况。Channel 提供从网络读取数据的渠道,但是读取或写入的数据都必须经由 Buffer.


image.png

Buffer常用API介绍

image.png

在 NIO 中,Buffer是一个顶层父类,它是一个抽象类, 类的层级关系图,常用的缓冲区分别对应
byte,short, int, long,float,double,char 7种.

1.缓冲区对象创建

方法名 说明
static ByteBuffer allocate(长度) 创建byte类型的指定长度的缓冲区
static ByteBuffer wrap(byte[] array) 创建一个有内容的byte类型缓冲区
//1.创建一个指定长度的缓冲区, 以ByteBuffer为例 
ByteBuffer byteBuffer = ByteBuffer.allocate(5);
//2.创建一个有内容的缓冲区 
ByteBuffer wrap = ByteBuffer.wrap("lagou".getBytes());

2.缓冲区对象添加数据

方法名 说明
int position()/position(intnewPosition) 获得当前要操作的索引/修改当前要操作的索引位置
int limit()/limit(int newLimit) 最多能操作到哪个索引/修改最多能操作的索引位置
int capacity() 返回缓冲区的总长度
int remaining()/booleanhasRemaining() 还有多少能操作索引个数/是否还有能操作
put(byte b)/put(byte[] src) 添加一个字节/添加字节数组
image.png

代码示例
···
public static void main(String[] args) {
//1.创建一个缓冲区
ByteBuffer allocate = ByteBuffer.allocate(10);
System.out.println(allocate.position());//0 获取当前索引所在位置
System.out.println(allocate.limit());//10 最多能操作到哪个索引位置
System.out.println(allocate.capacity());//10 返回缓冲区总长度
System.out.println(allocate.remaining());//10 还有多少个可以操作的个数

    System.out.println("----------------");
    // 修改当前索引所在位置
    //allocate.position(1);
    // 修改最多能操作到哪个索引的位置
    //allocate.limit(9);
    // System.out.println(allocate.position());//1 获取当前索引所在位置
    //System.out.println(allocate.limit());//9 最多能操作到哪个索引位置
    //System.out.println(allocate.capacity());//10 返回缓冲区总长度
    //System.out.println(allocate.remaining());//8 还有多少个可以操作的个数

    // 添加一个字节
    allocate.put((byte) 97);
    System.out.println(allocate.position());//1 获取当前索引所在位置
    System.out.println(allocate.limit());//10 最多能操作到哪个索引位置
    System.out.println(allocate.capacity());//10 返回缓冲区总长度
    System.out.println(allocate.remaining());//9 还有多少个可以操作的个数

    System.out.println("----------------");
    // 添加一个数组
    allocate.put("abc".getBytes());
    System.out.println(allocate.position());//4 获取当前索引所在位置
    System.out.println(allocate.limit());//10 最多能操作到哪个索引位置
    System.out.println(allocate.capacity());//10 返回缓冲区总长度
    System.out.println(allocate.remaining());//6 还有多少个可以操作的个数
    System.out.println("----------------");
    // 添加一个数组
    allocate.put("123456".getBytes());
    System.out.println(allocate.position());//10 获取当前索引所在位置
    System.out.println(allocate.limit());//10 最多能操作到哪个索引位置
    System.out.println(allocate.capacity());//10 返回缓冲区总长度
    System.out.println(allocate.remaining());//0 还有多少个可以操作的个数
    System.out.println(allocate.hasRemaining());//false 是否还能操作
    System.out.println("----------------");
    //如果缓冲区满了. 可以调整position位置, 就可以重复写. 会覆盖之前存入索引位置的值
    allocate.position(0);
    allocate.put("123456".getBytes());
    System.out.println(allocate.position());//6 获取当前索引所在位置
    System.out.println(allocate.limit());//10 最多能操作到哪个索引位置
    System.out.println(allocate.capacity());//10 返回缓冲区总长度
    System.out.println(allocate.remaining());//4 还有多少个可以操作的个数
    System.out.println(allocate.hasRemaining());//true 是否还能操作

}

···

3.缓冲区对象读取数据

方法名 说明
flip() 写切换读模式 limit设置position位置, position设置0
get() 读一个字节
get(byte[] dst) 读多个字节
get(int index) 读指定索引的字节
rewind() 将position设置为0,可以重复读
clear() 切换写模式 position设置为0 , limit 设置为 capacity
array() 将缓冲区转换成字节数组返回

flip()方法

image.png

clear()方法

image.png
  public static void main(String[] args) {
        //1.创建一个指定长度的缓冲区
        ByteBuffer allocate = ByteBuffer.allocate(10);
        allocate.put("0123".getBytes());
        System.out.println("position:" + allocate.position());//4
        System.out.println("limit:" + allocate.limit());//10
        System.out.println("capacity:" + allocate.capacity());//10
        System.out.println("remaining:" + allocate.remaining());//6

        //切换读模式
        System.out.println("读取数据--------------");
        allocate.flip();
        System.out.println("position:" + allocate.position());//4
        System.out.println("limit:" + allocate.limit());//10
        System.out.println("capacity:" + allocate.capacity());//10
        System.out.println("remaining:" + allocate.remaining());//6
        for (int i = 0; i < allocate.limit(); i++) {
            System.out.println(allocate.get());
        }
        //读取完毕后.继续读取会报错,超过limit值
        //System.out.println(allocate.get());
        //读取指定索引字节
        System.out.println("读取指定索引字节--------------");
        System.out.println(allocate.get(1));

        System.out.println("读取多个字节--------------");
        // 重复读取
        allocate.rewind();
        byte[] bytes = new byte[4];
        allocate.get(bytes);
        System.out.println(new String(bytes));

        // 将缓冲区转化字节数组返回
        System.out.println("将缓冲区转化字节数组返回--------------");
        byte[] array = allocate.array();
        System.out.println(new String(array));

        // 切换写模式,覆盖之前索引所在位置的值
        System.out.println("写模式--------------");
        allocate.clear();
        allocate.put("abc".getBytes());
        System.out.println(new String(allocate.array()));

    }

注意事项:

  1. capacity:容量(长度)limit: 界限(最多能读/写到哪里)posotion:位置(读/写
    哪个索引)
  2. 获取缓冲区里面数据之前,需要调用flip方法
  3. 再次写数据之前,需要调用clear方法,但是数据还未消失,等再次写入数据,被覆盖了
    才会消失。
上一篇下一篇

猜你喜欢

热点阅读