NIO中Buffer缓冲区的核心要点

一.buffer缓冲区核心要点

我们来看看Buffer缓冲区有什么值得我们注意的地方。

Buffer是缓冲区的抽象类:

14534869-cc5fac36a3e367c8.jpg
buffer抽象类源码.jpg

其中ByteBuffer是用得最多的实现类(在管道中读写字节数据)。

14534869-8920e642361d1d24.jpg
buffer实现类.jpg

拿到一个缓冲区我们往往会做什么?很简单,就是读取缓冲区的数据/写数据到缓冲区中。所以,缓冲区的核心方法就是:

  • put()
  • get()

Buffer类维护了4个核心变量属性来提供关于其所包含的数组的信息。它们是:

  • 容量Capacity
    • 缓冲区能够容纳的数据元素的最大数量。容量在缓冲区创建时被设定,并且永远不能被改变。(不能被改变的原因也很简单,底层是数组嘛)
  • 上界Limit
    • 缓冲区里的数据的总数,代表了当前缓冲区中一共有多少数据。
  • 位置Position
    • 下一个要被读或写的元素的位置。Position会自动由相应的 get( )put( )函数更新。
  • 标记Mark
    • 一个备忘位置。用于记录上一次读写的位置
14534869-e848074ae51b10d4.jpg
buffer要点.jpg

二.buffer代码演示

首先展示一下是如何创建缓冲区的,核心变量的值是怎么变化的


    public static void main(String[] args) {

        // 创建一个缓冲区
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);

        // 看一下初始时4个核心变量的值
        System.out.println("初始时-->limit--->"+byteBuffer.limit());
        System.out.println("初始时-->position--->"+byteBuffer.position());
        System.out.println("初始时-->capacity--->"+byteBuffer.capacity());
        System.out.println("初始时-->mark--->" + byteBuffer.mark());

        System.out.println("--------------------------------------");

        // 添加一些数据到缓冲区中
        String s = "Java3y";
        byteBuffer.put(s.getBytes());

        // 看一下初始时4个核心变量的值
        System.out.println("put完之后-->limit--->"+byteBuffer.limit());
        System.out.println("put完之后-->position--->"+byteBuffer.position());
        System.out.println("put完之后-->capacity--->"+byteBuffer.capacity());
        System.out.println("put完之后-->mark--->" + byteBuffer.mark());
    }
复制代码

运行结果:

14534869-9b4a6be94b4eef59.jpg
初始时4个核心变量的值

现在我想要从缓存区拿数据,怎么拿呀??NIO给了我们一个flip()方法。这个方法可以改动position和limit的位置

还是上面的代码,我们flip()一下后,再看看4个核心属性的值会发生什么变化:

14534869-c7e7cc59b6816798.jpg
flip之后

很明显的是:

  • limit变成了position的位置了
  • 而position变成了0

看到这里的同学可能就会想到了:当调用完filp()时:limit是限制读到哪里,而position是从哪里读

一般我们称filp()切换成读模式

  • 每当要从缓存区的时候读取数据时,就调用filp()切换成读模式
14534869-19c479ba687d540d.jpg
buffer结构.jpg

切换成读模式之后,我们就可以读取缓冲区的数据了:


        // 创建一个limit()大小的字节数组(因为就只有limit这么多个数据可读)
        byte[] bytes = new byte[byteBuffer.limit()];

        // 将读取的数据装进我们的字节数组中
        byteBuffer.get(bytes);

        // 输出数据
        System.out.println(new String(bytes, 0, bytes.length));

随后输出一下核心变量的值看看:

14534869-de27ac3388382ffc.jpg
核心变量的变化.jpg

读完我们还想写数据到缓冲区,那就使用clear()函数,这个函数会“清空”缓冲区:

  • 数据没有真正被清空,只是被遗忘掉了
14534869-e4f3e4cd4a4e3f2d.jpg
clear之后.jpg

参考自:https://juejin.im/post/5af942c6f265da0b7026050c

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值