bytebuffer ByteBuffer 介绍及 C+实现

栏目:时尚 2021-09-17 14:42:47
分享到:

1.字节缓冲器介绍

2.字节缓冲区的成员变量

2.1几个位置变量

2.2缓冲区

2.3字节缓冲名称

3.创建字节缓冲区

3.1创建指定大小的空字节缓冲区

3.2从数组中创建指定大小的字节缓冲区

3.3解构的方法

4.与状态相关

4.1初始状态

4.2写状态

4.3读取状态

4.4标记和丢弃标记

4.5复位

4.6倒带

4.7紧凑型

4.8状态相关方法概述

5.输入数据

5.1产能扩张机制

5.2模板法

5.3摆放方法

6.检索数据

6.1模板法

6.2获取方法

7.其他方法

7.1等于

7.2副本

7.3剩余

7.4剩余

7.5打印信息

8.字节缓冲的缺点

字节缓冲的介绍及其在C++中的实现

在之前的工作中,我遇到过打包数据并通过USB发送的功能。当时我写了一个简单的类来存储各种类型的数据,然后将数据发送到它的Buffer中,收到数据后再通过它的方法取出各种类型的数据。后来接触到Java的ByteBuffer,发现两个函数大致相同。本文将使用C++来实现ByteBuffer的大部分功能。

1.字节缓冲器介绍

ByteBuffer类位于java.nio package下,是一个字节缓冲区,提供了一些put和get方法,可以方便地将一些数据放入缓冲区或者从缓冲区中读取某种类型的数据。ByteBuffer的底层存储结构是一个数组,所有操作都基于这个数组。

以下内容结合Java ByteBuffer的原理和C++的实现进行说明。

2.字节缓冲区的成员变量

2.1几个位置变量

这四个变量之间的关系可以表示为:。

保存和读取数据只会影响位置,不会限制。

在C++实现中,设置以下成员变量:

提供以下三种方法分别获取容量、位置和极限:

有两种方法可以重置极限和位置:

2.2缓冲区

如前所述,字节缓冲区提供了存储数据的缓冲区。在C++实现中,一种类型的数组用于存储数据。ByteBuffer类的应用时间为空,销毁ByteBuffer类时的释放时间为空。

2.3字节缓冲名称

为了使打印美观,为每个字节缓冲区设置一个名称,它是字节缓冲区类的成员变量。创建类时设置,默认值为空:

3.创建字节缓冲区

Java.nio.Buffer类是抽象类,不能实例化。Buffer类的直接子类,比如ByteBuffer,也是抽象类,所以不能实例化。但是字节缓冲类提供了四种静态工厂方法来获取字节缓冲的实例:

C++版本得到了简化,并提供了两种创建方法。

3.1创建指定大小的空字节缓冲区

如果在创建时未指定,默认大小为2048字节。

3.2从数组中创建指定大小的字节缓冲区

该方法负责将现有数组的指定长度保存到字节缓冲区中,这将在后面描述。

3.3解构的方法

析构函数方法的主要功能是释放应用的内存:

4.与状态相关

要申请容量为10的字节缓冲区,以下演示基于。

4.1初始状态

图像-20210323235205921

在初始状态下,四个变量的值为:

标记:-1

位置:0

限制:10

容量:10

将字节缓冲区设置为初始状态的方法:

创建字节缓冲区后,它是调用其他方法之前的初始状态

调用方法重置为初始状态。

该方法的C++实现如下:

4.2写状态

假设写了几个字符,四个变量的状态如图所示:

图像-20210323235228538

写入数据时,位置会向后移动。

将字节缓冲区设置为写入状态的方法:

ByteBuffer在创建后写入,可以调用一系列方法写入数据;

4.3读取状态

进入读取状态时,四个变量的状态如下所示:

图像-20210324000012817

调用一系列方法来读取数据,这些方法将在读取数据时向后移动,但不会超过。

从写入状态进入读取状态时,需要调用方法。调用方法后,它被设置为原始值,指示存储数据的位置;设置为0。

该方法的C++实现如下:

4.4标记和丢弃标记

这两种方法都比较简单,方法是将标记值设置到当前位置;;该方法将标记重置为-1。调用和方法后,标记位置的变化如下所示:

这两种方法的C++代码实现如下:

4.5复位

方法将位置恢复到标记的位置。调用方法后,位置会发生变化,如图所示:

图像-20210324140402132

该方法的C++实现如下:

4.6倒带

方法负责设置为,设置标记为,数据内容不变,通常在将数据重写到Buffer之前调用。调用方法后的标记和位置变化如图所示:

图片-20210324140832110

该方法的C++实现如下:

4.7紧凑型

压缩缓冲区。将缓冲区当前位置和限制之间的数据移动到缓冲区的开头。也就是说,索引处的字节被复制到索引,索引p+1处的字节被复制到索引1。以此类推,直到limit-1处的字节被复制到索引中。然后将缓冲区的位置设置为n+1,并将限制值设置为容量。

调用方法后,几个变量的位置和数据的变化如下所示:

图像-20210324192748457

该方法的C++实现如下:

4.8状态相关方法概述

5.输入数据

Bytebuffer提供了一系列的put方法将各种类型的数据放入buffer,包括char、short、int、long、float、double、char数组和Bytebuffer。

5.1产能扩张机制

Java字节缓冲区在创建时具有固定的容量。如果存储的数据超出容量,将引发异常。ByteBuffer的C++版本增加了容量扩展机制。理论上,每次将数据写入缓冲区时,都需要检查空是否足够。如果空不够,容量会扩大。

ByteBuffer定义的成员变量表示扩展的步长,即每次扩展的容量是的整数倍,其值为2048:

定义检查容量是否足够的方法,如果足够就不要处理;如果不是,请计算需要多少容量并进行扩展:

在每个方法中,首先调用来检查容量,然后放入数据。

5.2模板法

为了简化存储数据的过程,使用模板方法来适应各种类型:

方法将数据写入当前,并相应地递增。

方法将数据写入指定位置,首先将设置为,然后调用方法写入数据。

5.3摆放方法

ByteBuffer提供的所有put方法的返回值类型都便于链式操作。例如,所有方法如下:

注意:因为Java采用Unicode编码,一个char类型占用两个字节,但是在C++中,Char类型占用一个字节,所以两个版本有一些区别。

将焦点放在方法上,该方法将另一个字节缓冲区的内容复制到当前的字节缓冲区,其实现如下:

6.检索数据

Bytebuffer提供了一系列get方法来将各种类型的数据放入buffer。

6.1模板法

为了简化数据采集,采用模板法采集各种类型的数据。注意:带参数的方法不会改变。

6.2获取方法

所有方法如下:

注意:带参数的方法不会改变值。

看看方法的实现:

为了只检查一次有效性,不调用模板方法。

7.其他方法

7.1等于

功能原型:

描述:比较两个字节缓冲区是否相等;

实现:

7.2副本

功能原型:

描述:复制字节缓冲区;;

实现:新字节缓冲区的标记为-1,与原来的字节缓冲区不同。

7.3剩余

功能原型:

说明:表示仓位和限额之间是否有数据;

实现:

7.4剩余

功能原型:

描述:返回位置和限制之间的字节数;

实现:

7.5打印信息

功能原型:

描述:打印标记、位置、极限和容量的值

实现:

8.字节缓冲的缺点

字节缓冲有以下缺点:

字节缓冲区不是线程安全的。如果您想在并发条件下使用它,您需要对缓冲区进行同步控制。

字节缓冲区有固定的长度。一旦分配完成,其容量就无法动态扩展和收缩。当要编码的对象大于字节缓冲区的容量时,将出现索引越界异常。

ByteBuffer只有一个指针位置,读写时需要手动调用。用户必须谨慎处理这些API,否则容易导致程序处理失败;

ByteBuffer的API功能有限,一些高级实用的功能不被它支持,需要用户自己编程。

本文的C++实现只调整了第二点,支持主动扩展;还有其他几个缺点。

它是Netty中封装的数据缓冲区,不同于ByteBuffer操作ByteBuffer数据读写需要位置、限制、容量等属性,而ByteBuff由两个指针辅助完成缓冲区的读写操作,可以实现C++版本的ByteBuffer,也可以后期修改当前的C++ ByteBuffer。

参考链接

class ByteBuffer:https://docs . Oracle . com/javase/7/docs/API/Java/nio/ByteBuffer . html

字节码的详细解释常见方法:https://blog.csdn.net/moakun/article/details/80630477

详细解释:http://bcoder.com/java/explaination-of-bytebuffer

图形字节缓冲区和字节缓冲区:https://www.gameboys.cn/article/193

点分享

点数收集

点击它