java nio Buffer基本用法

本文详细解析了Java NIO中的Buffer类,介绍了其关键属性如capacity、position、limit以及mark、reset、compact等方法的作用,通过实例展示了如何在读写模式切换和数据处理中灵活运用。

继承体系如下:

Buffer虽然是基类,但并没有定义数据的容器,仅仅定义了几个用来做标志的变量。

    private int mark = -1;
    private int position = 0;
    private int limit;
    private int capacity;

先说下面几个吧

capacity表示容器得大小,在ByteBuffer中对应数组的大小,一般需要人为指定,通常取值为1024或者1024的倍数。

position表示当前所在的地方

limit表示读写的限制。在写模式下,等于capacity,也就是最大容量;在读模式,等于buffer容器内现有数据的长度。

网上找个图过来(从上往下看,最上面是起点)

上面的图左右对照起来看,正是描述了从写模式切换到读模式的过程:将limit放到position所在的位置(表示最多能读取多少数据),再将postion置为0,从头开始读取刚才写入的数据。

对应于Buffer类中的flip()方法

    public final Buffer flip() {
        limit = position;
        position = 0;
        mark = -1;
        return this;
    }

其实在使用Buffer类时,我们通常会组合调用一些方法。

1、向Buffer内写数据

写操作时,我们通常会调用clear()方法清空容器。(这里的read是相对于流来说的,对于Buffer本身来说,是往里面放东西,是一个write的过程)

       buf.clear();     // Prepare buffer for reading
       in.read(buf);    // Read data

clear()方法仅仅通过修改标志来实现清空。

    public final Buffer clear() {
        position = 0;
        limit = capacity;
        mark = -1;
        return this;
    }

2、向Buffer内 写-读 数据

一般会先设置头信息,再写入主题信息,写操作做完后,切换为读模式

       buf.put(magic);    // Prepend header
       in.read(buf);      // Read data into rest of buffer
       buf.flip();        // Flip buffer
       out.write(buf);    // Write header + data to channel

3、倒带 rewind

适用于”读完一次不过瘾,还想再读一次“

       out.write(buf);    // Write remaining data
       buf.rewind();      // Rewind buffer
       buf.get(array);    // Copy data into array

rewind()将postion重新置为0

get()方法将buf内的数据再取出来一次,并放入数组。

rewind的主要逻辑如下

    public final Buffer rewind() {
        position = 0;
        mark = -1;
        return this;
    }

4、mark  reset

正如其字面含义,mark是用来做标记的,调用mark方法,标记当前position所在的位置。在必要的时候,调用reset方法,可以重新回到之前标志的地方。

    public final Buffer mark() {
        mark = position;
        return this;
    }

reset()

    public final Buffer reset() {
        int m = mark;
        if (m < 0)
            throw new InvalidMarkException();
        position = m;
        return this;
    }

5、compact方法

网上有很多博客对其描述都有点问题。

我需要读取 A B C D E F  这几个数,此时我读取到了B,还剩下CDEF没有读,调用compact方法后,将CDEF拷贝数组的最前端,并且让postion指向F。

为啥执行F而不是指向0呢?

主要是为了解决这个场景下遇到的问题:在进行读操作时,突然不想读了,我想进行写操作,等写完剩余的数据后,我再flip一下,从头开始读取。

这种情况下,就可以使用compact方法,将剩下没来得及读取的数copy到数组的首部,并把position置为剩余数据尾部,注意是剩余数据尾部,而不是头部。

看一下源码的实现:

    public ByteBuffer compact() {

        System.arraycopy(hb, ix(position()), hb, ix(0), remaining());
        position(remaining());
        limit(capacity());
        discardMark();
        return this;
    }

ix是给他加一个偏移量,可以先不考虑。整个的逻辑就是将剩余未读的地方拷贝到数组的最前面,并把positon移动到数据的末尾。

 

配合之前写的一篇demo食用更佳:java nio简单示例:实现客户端与服务器一问一答

 

参考:

http://ifeve.com/buffers/

http://ifeve.com/buffers/#clearandcompact

 

【高创新!高热点!】基于蚂蚁算法、A算法、RRT算法的三维无人机路径规划比较与研究(Matlab代码实现)内容概要:本文围绕基于蚂蚁算法、A算法和RRT算法的三维无人机路径规划展开比较与研究,重点探讨三种智能优化算法在复杂三维空间环境下的路径搜索能力、效率与适应性。通过Matlab代码实现算法仿真,对比不同算法在避障、路径平滑度、收敛速度等方面的性能表现,旨在为无人机自主导航提供有效的路径规划解决方案。研究涵盖算法原理分析、模型构建、仿真实验设计及结果对比,突出高创新性和研究热点特性。; 适合人群:具备一定编程基础,熟悉Matlab工具,从事无人机、智能优化算法、路径规划等相关方向的科研人员及研究生。; 使用场景及目标:① 掌握蚂蚁算法、A*算法和RRT算法的基本原理及其在三维路径规划中的实现方式;② 对比不同算法在实际仿真环境中的性能差异,选择适用于特定场景的最优路径规划方法;③ 为后续开展无人机自主导航、智能避障等研究提供算法选型依据和技术支持。; 阅读建议:建议结合提供的Matlab代码进行仿真实践,深入理解各算法的核心参数设置与调优策略,重点关注仿真结果的可视化分析,以便更直观地把握算法性能差异。同时可拓展至动态环境或多无人机协同路径规划的研究。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值