在 Web 开发中,当我们处理文件时(创建,上传,下载),经常会遇到二进制数据。另一个典型的应用场景是图像处理。
这些都可以通过 JavaScript 进行处理,而且二进制操作性能更高。
不过,在 JavaScript 中有很多种二进制数据格式,会有点容易混淆。仅举几个例子:
- ArrayBuffer,Uint8Array,DataView,Blob,File 及其他。
ArrayBuffer 二进制数组
基本的二进制对象是 ArrayBuffer —— 对固定长度的连续内存空间的引用。
let buffer = new ArrayBuffer(16); // 创建一个长度为 16 的 buffer
alert(buffer.byteLength); // 16
它会分配一个 16 字节的连续内存空间,并用 0 进行预填充。
注意:ArrayBuffer 并不是一个数组,它只是一个连续的内存区域,仅仅用来暂存一下数据。
操作 ArrayBuffer 中的数据
ArrayBuffer
是核心对象,是所有的基础,是原始的二进制数据。
如果要操作 ArrayBuffer,我们需要使用“视图”对象。
视图对象本身并不存储任何东西。它是一副“眼镜”,透过它来解释存储在 ArrayBuffer 中的字节。同样的东西用不同的方式来解析是不同的。
比如同样一个 16 字节 ArrayBuffer 中的二进制数据可以解释为 16 个“小数字”,或 8 个更大的数字(每个数字 2 个字节),或 4 个更大的数字(每个数字 4 个字节),或 2 个高精度的浮点数(每个数字 8 个字节)。
类型化视图
这里默认提供了几副固定了视角的眼镜:
Uint8Array
—— 将 ArrayBuffer 中的每个字节视为 0 到 255 之间的单个数字(每个字节是 8 位,因此只能容纳那么多)。这称为 “8 位无符号整数”。Uint16Array
—— 将每 2 个字节视为一个 0 到 65535 之间的整数。这称为 “16 位无符号整数”。Uint32Array
—— 将每 4 个字节视为一个 0 到 4294967295 之间的整数。这称为 “32 位无符号整数”。Float64Array
—— 将每 8 个字节视为一个 5.0x10-324 到 1.8x10308 之间的浮点数。
DataView
DataView 是在 ArrayBuffer 上的一种特殊的超灵活“未类型化”视图。上面类型化的眼镜,一戴上视角就固定了,所有的数据都已固定格式解析。而 DataView 这幅眼镜,视角是可调的,戴上后,想要什么视角就能调什么视角。
- 对于类型化的数组,构造器决定了其格式。整个数组应该是统一的。第 i 个数字是 arr[i]。
- 通过 DataView,我们可以使用 .getUint8(i) 或 .getUint16(i) 之类的方法访问数据。我们在调用方法时选择格式,而不是在构造的时候。
TextDecoder 和 TextEncoder
内建的 TextDecoder
对象在给定缓冲区(buffer)和编码格式(encoding)的情况下,允许将值读取为实际的 JavaScript 字符串。
- 例如,我们收到了一个包含文本数据的文件,TextDecoder 可以解析为文本。
TextEncoder
做相反的事情 —— 将字符串转换为字节。
Blob
arrayBuffer,Uint8Array 及其他 BufferSource 是“二进制数据”,而 Blob
则表示“具有类型的二进制数据”,比 arrBuffer 层级更高。
Blob 带类型,所以很容易解析成对应文件,可以将 Blob 看成某种文件的二进制形式。比如图片的二进制形式。
又因为 Blob 的类型通常是 MIME 类型,所以 Blob 对象很适用于在浏览器中上传/下载。
XMLHttpRequest,fetch 等进行 Web 请求的方法可以自然地使用 Blob,当然也可以使用其他类型的二进制数据。
我们可以轻松地在 Blob 和低级别的二进制数据类型之间进行转换:
- 我们可以使用
new Blob(...)
构造函数从一个类型化数组(typed array)中创建 Blob。 - 反过来,我们也可以使用
blob.arrayBuffer()
从 Blob 中取回 arrayBuffer,然后在其上创建一个视图(view),用于低级别的二进制处理。
当我们需要处理大型 blob 时,将其转换为 stream
非常有用。你可以轻松地从 blob 创建 ReadableStream
。Blob 接口的 stream()
方法返回一个 ReadableStream,其在被读取时返回 blob 中包含的数据。
Blob 组成
Blob 由一个可选的字符串 type()和 blobParts 组成。blobParts 部分通常是一系列其他 Blob 对象,字符串 或 BufferSource。
构造函数的语法为:
new Blob(blobParts, options