NodeJS中的Buffer是什么

NodeJS中的Buffer是什么

Buffer,也称为缓冲区,是原始内存中的特定位置。 它用作处理单元在特定时刻无法接受的多余二进制数据的临时存储空间。

Node.js 包含一个 Buffer 类。 它可以在管理 TCP流和文件系统上的读写操作时处理二进制数据。

创建Buffer

要在 Node.js 中创建Buffer,您将使用 alloc() 或 from() 方法。 alloc() 方法创建一个新缓冲区,在创建期间将其大小指定为第一个也是唯一一个必需的参数。 当您在创建缓冲区时没有任何数据要存储时,它很有用,当您使用 alloc() 方法创建缓冲区时,以字节为单位指定缓冲区大小参数。 例如:

const buf = Buffer.alloc(8);
console.log(buf);
// output: <Buffer 00 00 00 00 00 00 00 00>

当您使用 alloc() 方法创建新数据时,Buffer 类会自动添加零作为占位符值。Buffer 类使用十六进制格式将每个 0 值表示为 00。 在此示例中,它总共包含八个值。要使用不同的占位符值初始化 Buffer,请传递第二个填充参数:

const buf_filled = Buffer.alloc(8, 5);
console.log(buf_filled);
// output: <Buffer 05 05 05 05 05 05 05 05>

该对象引用内存中存储值 05 的 8 个字节的部分。请注意,尽管您传递了一个数字作为填充参数,但缓冲区仅以二进制形式存储数据。为Buffer分配内存后,调用write()方法写入数据:

const buf = Buffer.alloc(8);

buf.write("v", "utf-8");
console.log(buf)
// output: <Buffer 76 00 00 00 00 00 00 00>

buf.write("va","utf-8");
console.log(buf)
// output: <Buffer 76 61 00 00 00 00 00 00>

write()方法使用字符编码将第一个参数转换为utf-8,然后将字符串写入Buffer。 向字符串中添加第二个字符将填满第二个字节。要从字符串或数组等现有数据类型中提取数据,请使用 from() 方法。 此方法从字符串和数组创建缓冲区,例如:

// String
const stringBuf = Buffer.from('string')
console.log(stringBuf)
// output: <Buffer 73 74 72 69 6e 67>

// Array
const arrayBuf = Buffer.from([97, 114, 114, 97, 121], 'hex')
console.log(arrayBuf);
// output: <Buffer 61 72 72 61 79>

from() 方法将输入作为第一个参数,计算编码数据所需的字节数,然后将结果发送到 Buffer。 通过提供另一种编码格式作为第二个参数,您可以覆盖默认编码 (UTF-8)。将数字传递给 from() 方法将导致错误。

读取Buffer

尽管缓冲区类似于数组,但它们不可调整大小,并且由于内置方法可以处理二进制计算机数据。Buffer 类允许我们使用 JavaScript 的方括号语法读取其数据的各个字节,例如:

const myBuf = Buffer.from('Mine');
console.log(MyBuf[1]);
// output: 105

console.log(MyBuf[3]);
// output: 101

console.log(MyBuf[5]);
// output: undefined

上面的代码块使用方括号语法来获取十进制表示形式的第一个和第三个字节的值。 尝试获取无效字节将导致未定义的错误。为了访问它的所有数据,Buffer 类带有方法 toJSON() 和 toString(),它们以两种不同的格式获取内容,toString() 方法输出一个字符串作为缓冲区内容:

const myBuf = Buffer.from('Mine');
console.log(myBuf.toString());
// output: 'Mine'

const numberBuf = Buffer.from([123]);
console.log(numberBuf.toString())
// output: '{'

const emptyBuf = Buffer.alloc(5);
console.log(emptyBuf.toString());
// output: '\\x00\\x00\\x00\\x00\\x00'

第一次调用使用值“Mine”初始化 Buffer,对 toString 的调用复制了该值。 第二个示例使用单整型数组进行初始化,它具有作为“{”字符的字符串表示形式。 在最后一种情况下,具有五个空值的 Buffer 返回字符串“\x00\x00\x00\x00\x00”。 字符串 \x00 是 null 的十六进制表示。

toString() 方法始终以字符串格式输出结果,无论您用什么类型的数据初始化 Buffer。.toJSON() 方法返回 Buffer 数据的十进制表示形式,无论您用于初始化 Buffer 的数据是什么,例如:

const myBuf = Buffer.from('Mine');
console.log(myBuf.toJSON());
// output: { type: 'Buffer', data: [ 77, 105, 110, 101 ] }

JSON 输出具有一个值为 Buffer 的类型属性以指示其来源。 它的数据属性存储一个表示原始字节数组的小数数组。

修改Buffer

与访问 Buffer 的单个字节类似,您还可以使用方括号语法修改 Buffer 内容的单个字节。使用方括号语法更改单个内容时,只能分配值的十进制表示形式,例如:

myBuf[0] = 70
console.log(myBuf.toString())
// output: 'Fine'

因为缓冲区是二进制数据,所以不能给缓冲区的特定部分一个字符串。 如果您尝试将单个字节设置为字符串,Buffer 会将其转换为空字符,例如:

myBuf[0] = 'F';
console.log(myBuf.toString());
// output: '\\x00ine'

另外,您可以使用 write() 方法更改缓冲区的全部内容。考虑在 Buffer 的长度之外插入一个索引。 Buffer 不会返回错误,而是忽略无效索引并保持原始 Buffer 内容不变,例如,尝试通过 114 的十进制表示将 myBuf 的第五个元素设置为 r:

myBuf[4] = 114;
console.log(myBuf.toString());
// output: 'Mine'

请注意,toString() 方法返回相同的值“Mine”。由于您无法调整 Buffer 的大小,因此尝试写入比一个人所能容纳的更多的数据将导致它丢弃额外的数据。 例如:

const buf1 = Buffer.alloc(5)
buf1.write('number');
console.log(buf1.toString())
// output: 'numbe'

使用 toString() 方法确认缓冲区数据,它返回‘numbe’而不是‘number’。 这是 write() 方法中插入的参数。

缓冲区从索引零开始以串行方式写入。 write() 方法连续地将字节添加到 Buffer,覆盖之前的任何数据,例如:

const buf2 = Buffer.alloc(6);

buf2.write('member');
console.log(buf2.toString())
// output: 'member'

buf2.write('hi');
console.log(buf2.toString());
// output: 'himber'

上面的代码创建了一个六字节缓冲区,并使用 write() 方法将字符串“member”添加到其中。然后它用新内容更新缓冲区,新内容比之前的内容占用更少的内存空间。这导致创建一个新字符串,其中前两个字节被覆盖,其余字节保持不变。

许多 API 和数据结构都使用缓冲区

现在您知道了如何创建缓冲区、写入缓冲区、读取其内容以及使用适当的方法对其进行修改。

还有其他几种方法可用于处理 Node.js Buffer 类。

您应该了解这些方法并了解缓冲区,以掌握流和文件系统等不同概念的工作原理。