ByteBuffer的用法[通俗易懂]

ByteBuffer的用法[通俗易懂]ByteBuffer也许很多人不常用,其实它是最常用的缓冲区,可以负责缓冲存储一段数据,供数据的写入和读取。ByteBuffer是NIO里用得最多的Buffer。ByteBuffer最核心的方法是put(byte)和get()。分别是往ByteBuffer里写一个字节,和读一个字节。值得注意的是,ByteBuffer的读写模式是分开的,正常的应用场景是:往ByteBuffer里写一些数

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

ByteBuffer的用法[通俗易懂]

遵循:BY-SA

署名-相同方式共享 4.0协议

作者:谭东

时间:2016年10月30日

环境:Windows 7

ByteBuffer也许很多人不常用,其实它是最常用的缓冲区,可以负责缓冲存储一段数据,供数据的写入和读取。ByteBuffer是NIO里用得最多的Buffer。

ByteBuffer最核心的方法是put(byte)get()。分别是往ByteBuffer里写一个字节,和读一个字节。

值得注意的是,ByteBuffer的读写模式是分开的,正常的应用场景是:往ByteBuffer里写一些数据,然后flip(),然后再读出来。

我们先来看看ByteBuffer的几个主要的方法。

1、如何创建一个ByteBuffer?

可以通过,ByteBuffer buffer=ByteBuffer.allocate(256);创建或者 ByteBuffer buffer=ByteBuffer.wrap(byteArray);这里的byteArray可以包含了数据,相当于写入了数据到缓冲区。

2、如何写入数据到ByteBuffer?

可以通过ByteBuffer buffer=ByteBuffer.wrap(byteArray);写入数据或者buffer.put(bytes);方法写入数据。

3、如何把数据准备为数据传出状态?

调用buffer.flip();

4、如何清除缓冲区?

buffer.clear(); 这个方法实际上也不会改变缓冲区的数据,而只是简单的重置了缓冲区的主要索引值,不必为了每次读写都创建新的缓冲区,那样做会降低性能。相反,要重用现在的缓冲区,在再次读取之前要清除缓冲区。

5、如何读取缓冲数据?

调用buffer.get(bytes);

接下来用图片展示看下ByteBuffer的一些属性和方法。

byte[] buff
buff即内部用于缓存的数组。
position
当前读取的位置。
mark
为某一读过的位置做标记,便于某些时候回退到该位置。
capacity
初始化时候的容量。
limit
读写的上限,limit<=capacity。

put

写模式下,往buffer里写一个字节,并把postion移动一位。写模式下,一般limit与capacity相等。

ByteBuffer的用法[通俗易懂]

flip

写完数据,需要开始读的时候,将postion复位到0,并将limit设为当前postion。

ByteBuffer的用法[通俗易懂]

get

从buffer里读一个字节,并把postion移动一位。上限是limit,即写入数据的最后位置。


ByteBuffer的用法[通俗易懂]

clear

将position置为0,并不清除buffer内容。


ByteBuffer的用法[通俗易懂]

mark相关的方法主要是mark()(标记)和reset()(回到标记)。

给大家两个例子:

这个代码是针对有数据的ByteBuffer,我们读取出来数据,写成文件的操作。之前用来做H264写文件用到的。仅供参考。

@Override
    public void onFrameAvailable(Object o) {
        ImgBufFrame imgBufFram = (ImgBufFrame) o;
        byte[] bytes = new byte[imgBufFram.buf.limit()];
        imgBufFram.buf.get(bytes);
        try {
            if (!write) {
                fout = new FileOutputStream(MyConfiguration.VIDEO_PATH + "/video.h264", true);
                write = true;
            }
            fout.write(bytes);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

下面这个例子是针对有数据的ByteBuffer,我们给他再写入一点头文件数据,之前用来做AAC裸流缺少ADTS头文件7位字节信息时,为AAC的每个缓冲加入前7位的ADTS头信息的。仅供参考。

 @Override
    public void onFrameAvailable(Object o) {
        AudioBufFrame audioBufFrame = (AudioBufFrame) o;
        int outBufferSize = audioBufFrame.buf.limit() + 7;
        byte[] aacBytes = new byte[outBufferSize];
        try {
            if (!write) {
                fout = new FileOutputStream(MyConfiguration.VIDEO_PATH + "/audio.aac");
                write = true;
            }
            addADTStoPacket(aacBytes, outBufferSize);
            audioBufFrame.buf.get(aacBytes, 7, audioBufFrame.buf.limit());
            fout.write(aacBytes);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
   /**
     * 添加ADTS头
     *
     * @param packet
     * @param packetLen
     */
    private void addADTStoPacket(byte[] packet, int packetLen) {
        int profile = 2; // AAC LC
        int freqIdx = 4; // 44.1KHz
        int chanCfg = 2; // CPE

        // fill in ADTS data
        packet[0] = (byte) 0xFF;
        packet[1] = (byte) 0xF9;
        packet[2] = (byte) (((profile - 1) << 6) + (freqIdx << 2) + (chanCfg >> 2));
        packet[3] = (byte) (((chanCfg & 3) << 6) + (packetLen >> 11));
        packet[4] = (byte) ((packetLen & 0x7FF) >> 3);
        packet[5] = (byte) (((packetLen & 7) << 5) + 0x1F);
        packet[6] = (byte) 0xFC;
    }

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/186691.html原文链接:https://javaforall.net

(0)
上一篇 2022年10月2日 下午5:36
下一篇 2022年10月2日 下午5:46


相关推荐

  • 搭建Android开发环境(超详细)

    搭建Android开发环境(超详细)文章转自:http://www.cnblogs.com/xdp-gacl/p/4322165.html搭建最新版本的Android开发环境  最近由于工作中要负责开发一款Android的App,之前都是做JavaWeb的开发,Android开发虽然有所了解,但是一直没有搭建开发环境去学习,Android的更新速度比较快了,Android1.0是2008年发布的,截止到目前为止And

    2022年7月23日
    6
  • 工具类之Python编译器Pycharm添加解释器

    工具类之Python编译器Pycharm添加解释器工具类之 Python 编译器 Pycharm 添加解释器连接远程服务器 1 点击左上角的 file 右键选择 setting 找到 projectinter 点击 showall 2 点击 号新增解释器 找到 sshinterpret 输入 host 服务器地址 port 端口号 username 用户名 点击 next 输入 password 密码 添加解释器注意 这里的服务器是已经安装了 Python 或 anaconda 的哦 1 选择远程解释器路径 一般在 root

    2026年3月27日
    4
  • 长尾分布(long-tail distribution)和长尾效应「建议收藏」

    长尾分布(long-tail distribution)和长尾效应「建议收藏」长尾分布(long-taildistribution)和长尾效应1、长尾效应作者:赵澈链接:https://www.zhihu.com/question/20027490/answer/20420381来源:知乎长尾效应其实是幂率分布的通俗提法,在物理上也被称为无标度现象,这种现象在自然界与社会生活中都相当地常见,可参考幂律分布_互动百科。里面也提到之所以叫无标度,是因为「系统中个体的尺度相差悬殊,缺乏一个优选的规模」。如下图这般,极少数个体(横轴)对应极高的值(纵轴),而拥有极低值的个体,数

    2025年7月11日
    5
  • [哎]关于ftp扫描工具的激活成功教程问题[通俗易懂]

    [哎]关于ftp扫描工具的激活成功教程问题[通俗易懂]先前发布过一个工具,用于ftp弱口令扫描 文章地址:http://blog.csdn.net/prsniper/article/details/6101770 当时为了吸引一些反汇编方面的高手交流,故意把DLL使用期限限制在2010年,可惜没人鸟我~~~~~~~~~

    2022年10月1日
    4
  • Midjourney操作指南,从账号注册到作品创作,带你玩转AI绘画

    Midjourney操作指南,从账号注册到作品创作,带你玩转AI绘画

    2026年3月15日
    2
  • C语言const详解

    C语言const详解const 在实际编程中用得并不多 const 是 constant 的缩写 意思是 恒定不变的 它是定义只读变量的关键字 或者说 const 是定义常变量的关键字 说 const 定义的是变量 但又相当于常量 说它定义的是常量 但又有变量的属性 所以叫常变量 用 const 定义常变量的方法很简单 就在通常定义变量时前面加 const 即可 如 constinta 10 const 和变量类型 int 可以互换位置 二者是等价的 即上条语句等价于 intconsta 1

    2026年3月16日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号