ArrayBuffer JS中的二进制数据处理

 

FileReader - Web API 接口 | MDN https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader#readAsArrayBuffer()

 

JS中的二进制数据处理

https://mp.weixin.qq.com/s/kgc966FWJFG7fE6eh5kfow
 

部门:业务技术/前端

 

 

前言

  在现有的计算机中,二进制常常以字节数组的形式存在于程序当中。例如在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 数组的差异主要在以下方面:

 

 
 
 
posted @ 2018-09-23 16:06  papering  阅读(722)  评论(0编辑  收藏  举报