JavaScript中各种二进制对象关系的深入讲解
Buffer
在 Node.js 中,Buffer 类被用来在 TCP 流、文件系统操作、以及其他上下文中处理二进制数据流。
创建 Buffer
Buffer 可以通过多种方式创建,在以下的代码片段中,我们来看如何创建一个空的 Buffer 对象。
const buf1 = Buffer.alloc(5);
console.log(buf1);
// 输出:<Buffer 00 00 00 00 00>
在上面的代码造片段中,我们使用 Buffer.alloc()
函数,创建一个大小为5的空 Buffer 对象 buf1
。Buffer 类中对应的成员函数总共包含4种:
Buffer.alloc(size[, fill[, encoding]])
: 创建一块Buffer空间,并全部用fill初始化,fill默认是0,encoding默认是utf8编码.Buffer.allocUnsafe(size)
: 创建一块Buffer堆内存,但是没有初始化.Buffer.allocUnsafeSlow(size)
: 创建一块未初始化的Buffer内存.Buffer.from(array)
: 根据参数生成一个新的 Buffer 对象。
写入和读出 Buffer
我们可以使用 buffer.write(string[, offset[, length]][, encoding])
函数来写入字符串到指定的 Buffer 对象中。
const buf2 = Buffer.alloc(5);
buf2.write("Hello");
console.log(buf2);
// 输出:<Buffer 48 65 6c 6c 6f>
在上面的代码片段中,我们在创建了一个 5 个字节大小的空 Buffer 对象 buf2
后,使用 buf2.write("Hello")
写入了字符串 "Hello",这里默认采用 utf8 编码(它是Buffer默认的编码方式)。
要打印出这个 Buffer 对象,我们使用 console.log
,看到一个新的数字数组 [ 72, 101, 108, 108, 111 ]
。这些数字代表了每个字符对应的 ASCII 码。
反过来,我们可以使用 buffer.toString()
函数把 Buffer 对象转换回字符串。
const buf3 = Buffer.from([72, 101, 108, 108, 111]);
console.log(buf3.toString());
// 输出:Hello
操作 Buffer
对于 Buffer 对象,我们可以使用三个函数 readInt8
、 readUInt8
、 writeUInt8
来读写其字节内容。
const buf4 = Buffer.alloc(2);
buf4.writeUInt8(16, 0);
buf4.writeUInt8(64, 1);
console.log(buf4.readUInt8(0));
console.log(buf4.readUInt8(1));
// 输出:16, 64
在上面的代码片段中,我们创建了一个大小为 2 个字节的 Buffer 对象 buf4
,并使用 buf4.writeUInt8(16,0)
和 buf4.writeUInt8(64,1)
分别向前两个字节写入了 16 和 64 两个数字。然后,我们使用 buf4.readUInt8(0)
和 buf4.readUInt8(1)
分别读取了前两个字节的内容。
ArrayBuffer & DataView
ArrayBuffer 和 DataView 是 HTML5 中新增的 TypedArray 的基础,用来处理二进制数据流。
ArrayBuffer
ArrayBuffer 对象用来表示一个通用的、固定长度的二进制数据缓冲区。在创建 ArrayBuffer 对象时,需要指定分配的内存大小(即容量),创建后,它们不能更改。
let buffer = new ArrayBuffer(16) // 创建一个大小为 16 个字节的 ArrayBuffer 对象
console.log(buffer.byteLength) // 输出:16
在上面的例子中,我们创建了一个大小为 16 个字节的 ArrayBuffer 对象,并且输出其占用的字节数,即16。
在 ArrayBuffer 对象中无法直接操作数据以及读取和写入,我们需要使用 DataView 对象来进行操作。
DataView
DataView 对象是一个用来读写 ArrayBuffer 的接口。与直接操作 ArrayBuffer 不同的是,DataView 可以针对不同的字节序进行解析,它可以指定数据在数组中的位置、以及数据的字节大小。
let buffer = new ArrayBuffer(16) // 创建一个大小为16字节的 ArrayBuffer 对象
let dataView = new DataView(buffer) // 创建一个针与buffer对前的 DataView 对象
dataView.setInt8(0, 1) // 将位置0的字节 编辑为1
dataView.setInt16(1, 37) // 将位置1到2的两个字节依次编辑为 0x0025,注意第一位是零
console.log(dataView.getInt8(0)) // 读取位置0的值,输出:1
console.log(dataView.getInt16(1)) // 读取位置1到2的2个字节,输出:37
在上面的例子中,我们创建了一个大小为 16 个字节的 ArrayBuffer 对象,并创建一个 DataView 对象来处理该 ArrayBuffer。我们使用 dataView.setInt8(0, 1)
将第一位字节位置上的值为 1
。然后使用 dataView.setInt16(1, 37)
将第二、第三位字节位置上的值依次为 0x25
。
最后,我们使用 dataView.getInt8(0)
和 dataView.getInt16(1)
分别读取类第一位字节和后两位字节,得到的值分别为 1
和 37
。
示例说明
- 实现一个往 ArrayBuffer 对象中写入和读出数据的示例
const buffer = new ArrayBuffer(8);
const dataView = new DataView(buffer);
// 往buffer中写入一些数据
dataView.setInt16(0, 256);
dataView.setInt32(2, 1024);
// 从buffer中读出数据
console.log(dataView.getInt16(0)); // 输出:256
console.log(dataView.getInt32(2)); // 输出:1024
在上面的例子中,我们创建了一个大小为 8 字节的 ArrayBuffer 对象,并通过 DataView 对象 dataView
来写入 256
和 1024
两个整型数。
- 实现一个从 Buffer 对象中复制数据到 ArrayBuffer 对象的示例
const buf = Buffer.from('this is a test');
const arrayBuffer = new ArrayBuffer(buf.length);
const view = new Uint8Array(arrayBuffer);
for (let i = 0; i < buf.length; i++) {
view[i] = buf[i];
}
console.log(view);
在上面的例子中,我们创建了一个大小等同于 buf
的 ArrayBuffer 对象 arrayBuffer
,并通过 view[i] = buf[i]
将 buf
中每个字节的数据都复制到 arrayBuffer
中,然后通过 console.log(view)
方法,打印出 arrayBuffer
内容。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript中各种二进制对象关系的深入讲解 - Python技术站