Buffer模块

319 阅读4分钟

无语了,Buffer模块又臭又长,而且我实际种几乎没用过,倒是有一次使用File文件的时候需要读buffer出来传入一个wasm转出来的函数。也就那样了,除了知道他是数据以外完全不知道有什么用,为什么用。

首先Buffer是什么?

  • 在 Node.js 中, Buffer 对象用于以字节序列的形式来表示二进制数据(考验计组功底了)。

  • 许多 Node.js 的 API(例如流和文件系统操作)都支持Buffer,因为与操作系统或其他进程的交互通常总是以二进制数据的形式。

  • Buffer 类是 JavaScript 语言内置的 Uint8Array 类的子类。 支持许多涵盖其他用例的额外方法。 只要支持 Buffer 的地方,Node.js API 都可以接受普通的 Uint8Array。

  • Buffer 类的实例,以及 普通Uint8Array类,类似于从 0 到 255之间的整数数组。

  • 一个 Buffer 的大小在创建时确定,且无法更改。

  • Buffer 类在全局作用域中,因此无需使用 require('buffer').Buffer。

// 看看官方的例子

// 创建一个长度为 10 的 Buffer,其中填充了全部值为 `0` 的字节。
const buf1 = Buffer.alloc(10);

// 创建一个长度为 10、且用 0x1 填充的 Buffer。 
const buf2 = Buffer.alloc(10, 1);

// 创建一个长度为 10、且未初始化的 Buffer。
// 这个方法比调用 Buffer.alloc() 更快,但返回的 Buffer 实例可能包含旧数据,
// 因此需要使用 fill()、write() 或其他能填充 Buffer 的内容的函数进行重写。
// 否则可能会泄露旧的数据
const buf3 = Buffer.allocUnsafe(10);

// 创建一个包含字节 [1, 2, 3] 的 Buffer。
const buf4 = Buffer.from([1, 2, 3]);

// 创建一个包含字节 [1, 1, 1, 1] 的 Buffer,
// 其中所有条目均使用 `(value & 255)` 进行截断以符合 0-255 的范围。
const buf5 = Buffer.from([257, 257.5, -255, '1']);

// 创建一个 Buffer,其中包含字符串 'tést' 的 UTF-8 编码字节:
// [0x74, 0xc3, 0xa9, 0x73, 0x74](以十六进制表示)
// [116, 195, 169, 115, 116](以十进制表示)
const buf6 = Buffer.from('tést');

// 创建一个包含 Latin-1 字节 [0x74, 0xe9, 0x73, 0x74] 的 Buffer。
const buf7 = Buffer.from('tést', 'latin1');

刚刚的实例们都看的比较清楚,字符 => 数字 ,无论是什么字符都被编成了数字,而这些数字就是我们所说的字节流。 这些数字在传输上有着比传输字符给更强的能力,我们在很多情况下需要他。 如何将字符转变为二进制流完全取决于你想要的编码方式,我们这就不多做讨论,我们只看看如何去使用它。

当在 Buffer 和字符串之间转换时,可以指定字符编码。 如果未指定字符编码,则使用 UTF-8 作为默认值。

const buf = Buffer.from('hello world', 'utf8');
console.log(buf.toString('hex'));
// 打印: 68656c6c6f20776f726c64
console.log(buf.toString('base64'));
// 打印: aGVsbG8gd29ybGQ=

console.log(Buffer.from('fhqwhgads', 'utf8'));
// 打印: <Buffer 66 68 71 77 68 67 61 64 73>
console.log(Buffer.from('fhqwhgads', 'utf16le'));
// 打印: <Buffer 66 00 68 00 71 00 77 00 68 00 67 00 61 00 64 00 73 00>

常用API

  • Buffer.alloc(size[, fill[, encoding]])

之前的例子也用了,感觉没什么好说的,就这样用。

分配一个大小为 size 字节的新 Buffer。 如果 fill 为 undefined,则用零填充 Buffer。

给些例子

const buf = Buffer.alloc(5);
console.log(buf);
// 打印: <Buffer 00 00 00 00 00>

const buf = Buffer.alloc(5, 'a');
console.log(buf);
// 打印: <Buffer 61 61 61 61 61>

调用 Buffer.alloc() 可能比替代的 Buffer.allocUnsafe() 慢得多,但能确保新创建的 Buffer 实例的内容永远不会包含来自先前分配的敏感数据。

  • Buffer.allocUnsafe(size)

以这种方式创建的 Buffer 实例是未初始化的。 Buffer 的内容可能包含敏感数据。

const buf = Buffer.allocUnsafe(10);
console.log(buf);
//  <Buffer a0 8b 28 3f 01 00 00 00 50 32>
buf.fill(0);
console.log(buf);
// <Buffer 00 00 00 00 00 00 00 00 00 00>

Buffer 模块会预分配一个内部的大小为 Buffer.poolSize 的Buffer实例,作为快速分配的内存池,用于使用Buffer.allocUnsafe() 创建新的 Buffer 实例、或 Buffer.from(array)

Buffer.alloc(size, fill) 永远不会使用内部的 Buffer 池

而 Buffer.allocUnsafe(size).fill(fill) 在 size 小于或等于 Buffer.poolSize 的一半时将会使用内部的 Buffer池。

该差异虽然很微妙,但当应用程序需要 Buffer.allocUnsafe() 提供的额外性能时,则非常重要。


感觉没啥好说的啊,这节主要还是需要自己深入了。涉及的知识比较难。