FileReader - Web API 接口 | MDN https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader#readAsArrayBuffer()
JS中的二进制数据处理
部门:业务技术/前端
前言
在现有的计算机中,二进制常常以字节数组的形式存在于程序当中。例如在C#里面,就用byte[],标准C里面没有byte类型,但可以通过typedef把byte定义为unsigned char的别名,效果是一样的。JS设计之初似乎就没想过要处理二进制,对于字节的概念可以说是非常非常的模糊。如果要表达字节数组,那么似乎只能用一个普通数组来表示。
然而随着业务需求的逐渐发展,出现了WebGL这样的技术。所谓WebGL,就是指浏览器与显卡之间的通信接口。为了满足JavaScript与显卡之间大量的、实时的数据交换,它们之间的数据通信必须是二进制的,而不能是传统的文本格式。类型化数组(Typed Array)就是在这种背景下诞生的。而类型化数组是建立在ArrayBuffer对象的基础上的。下面介绍一下Arraybuffer。
一、Arraybuffer
1.1 基本概念
ArrayBuffer 对象是 ES6 才纳入正式 ECMAScript 规范,是 JavaScript 操作二进制数据的一个接口。ArrayBuffer 对象是以数组的语法处理二进制数据,也称二进制数组。它不能直接读写,只能通过视图(TypedArray视图和DataView视图)来读写。
❝ArrayBuffer 简单说是一片内存,但是你不能直接用它。这就好比你在 C 里面,malloc 一片内存出来,你也会把它转换成 unsigned_int32 或者 int16 这些你需要的实际类型的数组/指针来用。这就是 JS 里的 TypedArray 的作用,那些 Uint32Array 也好,Int16Array 也好,都是给 ArrayBuffer 提供了一个 “View”,MDN 上的原话叫做 “Multiple views on the same data”,对它们进行下标读写,最终都会反应到它所建立在的 ArrayBuffer 之上。❝
1.2 基本操作
「语法」
new ArrayBuffer(length)
-
参数:length 表示要创建的 ArrayBuffer 的大小,单位为字节;
-
返回值:ArrayBuffer 对象;
-
异常:如果 length 大于 Number.MAX_SAFE_INTEGER(>= 2 ** 53)或为负数,则抛出一个 RangeError 异常;
「示例」
const buffer = new ArrayBuffer(32);
buffer.byteLength; // 32
const v = new Int32Array(buffer);
ArrayBuffer.isView(v) // true
const buffer2 = buffer.slice(0, 1);
上面代码表示实例对象 buffer 占用 32 个字节。
它有实例属性 byteLength ,表示当前实例占用的内存字节长度。
它拥有一个静态方法isView(),这个方法可以用来判断是否为TypedArray实例或DataView实例。
它拥有实例方法 slice(),用来复制一部分内存,使用方式同数组的slice方法。
除了slice方法,ArrayBuffer对象不提供任何直接读写内存的方法,只允许在其上方建立视图,然后通过视图读写。
二、视图
2.1 TypedArray
TypedArray一共包含九种类型,每一种都是一个构造函数。(DataView视图不支持Uint8ClampedArray,其他都支持)
名称 | 描述 | 长度(字节) |
---|---|---|
Int8Array | 8位有符号整数 | 1 |
Uint8Array | 8位无符号整数 | 1 |
Uint8ClampedArray | 8位无符号整型固定数组(数值在0~255之间) | 1 |
Int16Array | 16位有符号整数 | 2 |
Uint16Array | 16位无符号整数 | 2 |
Int32Array | 32位有符号整数 | 4 |
Uint32Array | 32 位无符号整数 | 4 |
Float32Array | 32 位 IEEE 浮点数 | 4 |
Float64Array | 64 位 IEEE 浮点数 | 8 |
每一种视图都有一个BYTES_PER_ELEMENT常数,表示这种数据类型占据的字节数。
Int8Array.BYTES_PER_ELEMENT // 1
Uint8Array.BYTES_PER_ELEMENT // 1
Int16Array.BYTES_PER_ELEMENT // 2
Uint16Array.BYTES_PER_ELEMENT // 2
Int32Array.BYTES_PER_ELEMENT // 4
Uint32Array.BYTES_PER_ELEMENT // 4
Float32Array.BYTES_PER_ELEMENT // 4
Float64Array.BYTES_PER_ELEMENT // 8
这 9 个构造函数生成的数组,统称为TypedArray视图。它们很像普通数组,都有length属性,普通数组的操作方法和属性,对TypedArray 数组完全适用。 普通数组与 TypedArray 数组的差异主要在以下方面: