手机版

JavaScript读写二进制数据的详细说明

时间:2021-08-30 来源:互联网 编辑:宝哥软件园 浏览:

前言

二进制是计算技术中广泛使用的一种数字系统。如果要在前端处理音频和视频,二进制数据是由0和1两个数字表示的数字。那么你必须掌握和操作好二进制数据。下面就不多说了,我们来看看详细的介绍

类型化数组的外观

类型化数组是HTML5中引入的一个API,它使开发人员能够使用JavaScript直接操作二进制数据。在类型化数组出现之前,我们无法通过JavaScript直接操作二进制数据,但我们通常会在JavaScript中操作数据类型,并在运行时将其转换为二进制数据。这增加了一个转换过程。虽然JavaScript对数据类型做了很多优化来提高效率,但是和直接二进制运算相比,效率还是有差别的。所以引入了类型化数组。

使用

那么,类型化数组有哪些应用场景呢?

画布图像处理。WebGL与显卡通信。如何使用Ajax响应进行文件操作

那么,既然类型化数组如此重要,你还在等什么呢?让我们快速掌握它们。

既然我们要直接操作二进制数据,并且二进制数据存储在一个连续的内存区域,那么我们首先要有这样一个内存区域。

我们可以创建一个内存区域:

let buffer=new arraybuffer()arraybuffer是一个构造函数,允许我们实例化一个数组缓冲区,可以理解为一个连续的内存区域。

因为我们的构造函数传入的参数是空的,生成的缓冲区指向的内存长度是0字节,没有意义。

好吧,让我们创建一个有意义的记忆区域。

Buffer=new ArrayBuffer(8)我们将参数8传递给ArrayBuffer,这意味着浏览器可以帮助我们创建一个长度为8字节的内存区域。

让我们看看这个内存区域的长度是否是8字节

console . log(buffer . bytelength);输出为8。看来浏览器没有欺骗我们。

我们猜测这8个字节中的所有值都应该是0,因为我们没有给buffer赋值。让我们确定一下,首先看第一个字节:

console.log(缓冲区[0])的输出:未定义。

啊?它是如何定义的?

哦,buffer[0]的原意是看buffer的属性0的值,因为buffer没有属性0,所以是未定义的。

看起来我们没有在正确的位置查看缓冲区。

那么如何查看缓冲区内容呢?

数组视图

八大金刚登场~

Int8array:长度为1字节的8位有符号整数。Uint8array:长度为1字节的8位无符号整数。Int16array:长度为2字节的16位有符号整数。Uint16array:长度为2字节的16位无符号整数。Int32array:长度为4字节的32位有符号整数。Uint32array:长度为4字节的32位无符号整数。Float32array:长度为4字节的32位浮点数。Float64array: 64位浮点数,8字节长。

这八大金刚有什么神奇的力量?我们不能直接读写缓冲区数据,这八种数据类型充当了读写缓冲区内容的桥梁。

还是上面的缓冲区,我们要检查缓冲区内容。首先,创建一个桥来读写缓冲区:

让int8Array=new Int8Array(缓冲区);我们创建了一个读写缓冲区的桥,使用8位有符号整数来读写缓冲区。现在,让我们看看缓冲区的第一个内容是什么。

console . log(int 8 array[0]);输出:0。似乎初始化时,缓冲区每个字节存储的值默认都是0。

让我们看看如何使用Int8Array为缓冲区赋值:

int 8 array[0]=30;int 8 array[1]=41;int 8 array[2]=52;int 8 array[3]=63;int 8 array[4]=74;int 8 array[5]=85;int 8 array[6]=86;int 8 array[7]=97;很简单,因为Int8Array的长度是一个字节,和buffer的单位一致,所以我们可以通过索引给buffer的指定位置赋值。

是不是很简单?就这么简单。

另外七个驴孔的用法和Int8Array一样,只是用法不同。让我们看看它们之间的区别。

这次我们用的是Int16Array,还是只是缓冲区。我们创造了一座新桥,它仍然通向缓冲区。

让int16Array=new Int16Array(缓冲区);想象一下int16Array[0]是什么。

让我们输出:

Console.log(int16Array[0])为什么结果是10526?

我不太明白。好,我们来分析一下10526是怎么来的。

让我们看看缓冲区中的二进制数据。

因为Int16Array占用两个字节,当我们用它读写数据时,一个索引所代表的数据等于缓冲区中的两个字节。

我们可以看到int16Array[0]中的二进制数据由30个二进制数据和41个二进制数据组成:0001110 (30) 00101001 (41)。

让我们按照30和41的顺序计算二进制对应的十进制数。

parsent(1111000101001,2) //输出7721的计算值是7721,和我们的输出不一致?

这涉及到字节顺序的概念。在我们的个人笔记本中,它通常是小端字节。在我们的例子中,小端字节顺序是41和30的二进制顺序。我们刚才的计算顺序有问题,按照41和30的二进制顺序计算

par sent(1010010011110,2)//输出10526,我们可以看到输出结果是10526,我们直接使用int16Array[0]

结果是一致的。

上面的例子告诉我们,当数据结构改为解析缓冲区时,数据会变得难以理解,所以一定要谨慎处理。

属性和方法

类型化数组实例化对象包含一些有用的属性和方法:

长度

length属性返回类型化数组的数据成员数。

字节长度

返回类型化数组的字节长度。注意和长度的区别。传递长度字节长度=长度*每个数据占用的字节数

字节集合

返回缓冲区中该类型化数组的数据开始的字节。

缓冲器

与类型化数组对应的缓冲区。

设置

复制数组,它将内存的一部分中的数据完全复制到另一部分中。

让a=新的uint 8 array(12);a[0]=31;a[1]=32;设b=新的uint 8 array(12);b . set(a);上面的代码意味着缓冲区a的内容被完全复制到缓冲区b,这比通过索引赋值要快得多。当然,set支持从索引中复制数据

让a=新的uint 8 array(12);a[0]=31;a[1]=32;设b=新的uint 8 array(10);b.set(a,2);上面的代码意味着从b的第三个索引位置复制a中的数据。

子阵列

Subarray的意思是获取一个类型化数组的内容并返回一个新的类型化数组。

让a=新的uint 8 array(8);a[2]=1;设b=a.subarray(2,3);console . log(b . length);console . log(b . Bytelengt);子数组的第一个参数表示从中截取的源数组的索引号,第二个参数表示从中截取的索引号。

混合视图

需要注意的一点是,当我们的类型数组初始化时,我们可以指定一段缓冲区,这意味着我们可以为一段缓冲区内存区域指定多个类型,这被称为混合视图。

让Buffer=new Buffer(8);设idArray=new Int8Array(buffer,0,2);让nameArray=new Int8Array(缓冲区,2,4);让ageArray=new Int8Array(缓冲区,6,2);我们用一个记忆区来代表一个人的身份证、姓名和年龄。这种结构类似于C语言中的结构。

我们将一个8字节的内存分成三个部分:

字节0 ~字节1代表id。字节2 ~字节5代表用户名。字节6 ~字节7代表年龄。数据视图

JavaScript还引入了另一种视图,DataView,也可以达到操作缓冲区的目的,但相比之下,DataView的粒度更细,还可以设置字节顺序是大是小。

数据视图的构造函数:

DataView(ArrayBuffer对象缓冲区,从缓冲区的哪个字节读取,读取长度);例如:

让buffer=new ArrayBuffer(10);let view=新的DataView(缓冲区);如何阅读?

我们已经创建了视图视图,那么如何阅读它呢?

GetInt8(索引,顺序):从索引字节中读取一个8位整数。GetUint8(索引,顺序):从索引字节中读取一个无符号的8位整数。GetInt16(索引,顺序):从索引字节中读取2个字节,并返回一个16位整数。GetUint16(index,order):从索引字节中读取2个字节,并返回一个无符号的16位整数。GetInt32(索引,顺序):从索引字节中读取4个字节,并返回一个32位整数。GetUint32(index,order):从索引字节中读取4个字节,并返回一个无符号的32位整数。GetFloat32(索引,顺序):从索引字节中读取4个字节,并返回一个32位浮点数。GetFloat64(索引,顺序):从索引字节中读取8个字节,并返回一个64位浮点数。JavaScript提供了八种阅读方法,简单易懂。这里就不举例了,大家可以自己试试。

正如我们刚才所说,DataView也支持设置字节顺序。在上面8中的读取模式中,第一个字节是索引,第二个字节允许我们设置字节顺序。true代表小端字节顺序读取,false代表大端字节顺序读取,默认值为false。

怎么写?

DataView不仅可以支持细粒度的读取操作,还可以支持细粒度的写入操作:

SetInt8(索引、值、顺序):从索引字节中,写入一个值为1字节的8位整数。SetUint8(索引、值、顺序):从索引字节中,写入一个值为1字节的无符号8位整数。SetInt16(索引、值、顺序):从索引字节中,写入2字节的16位带值整数。SetUint16(索引、值、顺序):从索引字节中,写入2字节的带值的无符号16位整数。SetInt32(索引、值、顺序):从索引字节中,写入4个字节的32位带值整数。SetUint32(索引、值、顺序):从索引字节中,写入4字节带值的无符号32位整数。SetFloat32(索引、值、顺序):从索引字节中,写入4个字节的32位带值浮点数。SetFloat64(索引、值、顺序):从索引字节中,写入8字节的64位带值浮点数。顺序仍然意味着写入时设置字节顺序。true是小字节顺序,false是大字节顺序,默认值为false。用法也很简单,可以练习。

至此,我们已经介绍完了JavaScript操作二进制的方式,当遇到需要直接内存操作的场景时,您可能希望使用这两种方式。

未来你会感谢你今天的努力。

摘要

以上就是本文的全部内容。希望本文的内容对大家的学习或工作有一定的参考价值。有问题可以留言交流。谢谢你的支持。

版权声明:JavaScript读写二进制数据的详细说明是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。