Skip to content
0

node:buffer

NodeJs 的 buffer 模块

Buffer

buffer 模块中提供了 Buffer 对象,用于开发者操作缓冲区。它也被直接暴露在了全局作用域当中

import buffer from 'node:buffer'

console.log(buffer.Buffer === Buffer) //=> true

创建一个缓冲区

使用 Buffer.from() 来创建缓冲区(new Buffer() 在 NodeJs 6 之后就不推荐使用了)

创建的四种形式

  • Buffer.from(string[, encoding])
  • Buffer.from(array)
  • Buffer.from(buffer)
  • Buffer.from(arrayBuffer[, byteOffset[, length]])
const buf = Buffer.from("hello buffer")
console.log(buf) //=> <Buffer 68 65 6c 6c 6f 20 62 75 66 66 65 72>

// 指定编码:
console.log(Buffer.from('peterroe', 'utf8'));
//=> <Buffer 70 65 74 65 72 72 6f 65>
console.log(Buffer.from('peterroe', 'utf16le'));
//=> <Buffer 70 00 65 00 74 00 65 00 72 00 72 00 6f 00 65 00>
console.log(Buffer.from('tést', 'latin1'));
//=> <Buffer 74 e9 73 74>

// 写的数据默认会被转为 2位 16进制
console.log(Buffer.from([255,3,44,0b101,0x44])) //=> <Buffer ff 03 2c 05 44>

// 超过 255 会溢出,从 0 重新开始计数(相当于执行了:value & 255)
console.log(Buffer.from([257, 3,44,3])) //=> <Buffer 01 03 2c 03>

// 输入十六进制
console.log(Buffer.from("2acb", "hex")) //=> <Buffer 2a cb>
// 奇数长度被截断
console.log(Buffer.from("2ac", "hex")) //=> <Buffer 2a>
// 非十六进制字符被截断
console.log(Buffer.from('1ag123', 'hex')) //=> <Buffer 1a>

如果在创建的时候,还没有准备好数据,可以使用 Buffer.alloc() 来申请一个空间,但是并不写入数据

const buf = Buffer.alloc(10)

写入数据

通过 .write() 可以写入数据

// ✅ 正确用法:
const buf = Buffer.alloc(100)
buf.write("hello buffer")

// ❌ 错误用法:
const buf = Buffer.from("hello buffer") 
// 通过 Buffer.from 创建的 buf,再写入数据是无效的 
buf.write("data")

填充数据

类似于字符串的 .fill()

const b = Buffer.alloc(10).fill('a')

console.log(b.toString())
//=> This will print aaaaaaaaaa

输出

提供了 toString()

type BufferEncoding = 'ascii'| 'utf8'| 'utf-8'| 'utf16le'| 'ucs2'| 'ucs-2'| 'base64'| 'base64url'| 'latin1'| 'binary'| 'hex';

console.log(Buffer.from("hello")) //=> <Buffer 68 65 6c 6c 6f>
console.log(Buffer.from("hello").toString()) //=> hello
console.log(Buffer.from("hello").toString('utf8')) //=> hello

console.log(Buffer.from([10,50,255]).toString('hex')) //=> 0a32ff

console.log(Buffer.from("peterroe").toString("base64")) //=> cGV0ZXJyb2U=

原型链

undefined
undefined

TypedArray

上面我们看到, Buffer 集成自 TypedArray,实际上 NodeJs 全局作用域中并不存在 TypedArray 这个对象,或者说允许通过 new TypedArray() 调用

MDN-TypedArray 中有说明:

1.TypedArray 对象描述了底层二进制数据缓冲区的类似数组的视图

2.有许多不同的全局属性,其值是特定元素类型的类型化数组构造函数

上面引用的第一点说明,我们可以通过类似遍历数组的方法来访问 Buffer 实例的每一项,而且这些方法并不来源于 Array

const buf = Buffer.from('xyz');
buf.forEach()
for (let [i, it] of buf.entries()) {
    console.log([i, it]);  // it: ASCII 中的编号
    // [ 0, 120 ] 
    // [ 1, 121 ]
    // [ 2, 122 ]
} 
console.log(buf instanceof Array) // => false

关于上面引用的第二点,NodeJs 提供了一系列的 TypedArray 对象,下面每一项都可以被称为特定类型TypedArray

TypeValue RangeSize in bytesWeb IDL type
Int8Array-128 to 1271byte
Uint8Array0 to 2551octet
Uint8ClampedArray0 to 2551octet
Int16Array-32768 to 327672short
Uint16Array0 to 655352unsigned short
Int32Array-2147483648 to 21474836474long
Uint32Array0 to 42949672954unsigned long
Float32Array-3.4e38 to 3.4e384unrestricted float
Float64Array-1.8e308 to 1.8e3088unrestricted double
BigInt64Array-2^63 to 2^63 - 18bigint
BigUint64Array0 to 2^64 - 18bigint

由原型链看来,我们的 Buffer,就是 Uint8Array 的一员,所以也有:

const buf = Buffer.alloc(10)
console.log(buf instanceof Uint8Array) //=> true

Buffers and TypedArrays

const arr = new Uint16Array(2);

arr[0] = 5000; // 相当于 0x1388
arr[1] = 4000; // 相当于 0xfa0

// 拷贝 arr 的内容.
const buf1 = Buffer.from(arr);
// 共享 arr 的内存
const buf2 = Buffer.from(arr.buffer);

console.log(buf1) // 默认创建的就是两位16进制,所以会被截断
// Prints: <Buffer 88 a0>
console.log(buf2)
// Prints: <Buffer 88 13 a0 0f>

arr[1] = 6000; // 相当于 0x1770

console.log(buf1);
// Prints: <Buffer 88 a0>
console.log(buf2);
// Prints: <Buffer 88 13 70 17>

ArrayBuffer

我们来介绍名字和 Buffer 有点像的 ArrayBuffer,后者与前者一个非常大的不同是,后者在浏览器和 NodeJs 环境都存在,但是使用起来有差别

ArrayBuffer对象用于表示通用的原始二进制数据缓冲区,它的定义非常原始和基础,所以我们要借助 TypedArray 来以特定的格式读取它的实例

const buffer = new ArrayBuffer(8);

const float32 = new Float32Array(buffer, 0, 2);
const unit8 = new Uint8Array(buffer, 0, 2);

console.log(float32.byteLength); // 8
console.log(float32); // [ 0, 0 ]
console.log(unit8.byteLength); // 2
console.log(unit8); // [ 0, 0 ]

let buf = Buffer.from(buffer)
buf.write('hello')

console.log(buf) // <Buffer 68 65 6c 6c 6f 00 00 00>

ArrayBuffer 在 NodeJs 中并不常创建使用,通常是利用 TypedArray 处理接收外部的数据

Released under the MIT License.