9. 缓冲区

纯JavaScript是Unicode友好的,但二进制数据却不是这样。 在处理TCP流或文件系统时,必须处理八位字节流。 Node提供了Buffer类,它提供了存储类似于整数数组的原始数据的实例,但对应于V8堆外部的原始内存分配。

Buffer类是一个全局类,可以在应用程序中访问而无需导入缓冲区模块。

9.1. 创建缓冲区

节点缓冲区可以以多种方式构建。

  • 以下是创建10 个八位字节的无启动缓冲区的语法:
    var buf = new Buffer(10);
    
  • 以下是从给定数组创建缓冲区的语法:
    var buf = new Buffer([10, 20, 30, 40, 50]);
    
  • 以下是从给定字符串创建缓冲区的语法,并可选择编码类型:
    var buf = new Buffer("Simply Easy Learning", "utf-8");
    

虽然“utf8”是默认编码,但您可以使用以下任何编码“ascii”,“utf8”,“utf16le”,“ucs2”,“base64”或“hex”。

9.2. 写入缓冲区

  • 语法:buf.write(string[, offset][, length][, encoding])
  • 参数:
    • string :这是要写入缓冲区的字符串数据。
    • offset :这是开始写入的缓冲区的索引。 默认值为0。
    • length :这是要写入的字节数。 默认为buffer.length。
    • encoding :要使用的编码。 ‘utf8’是默认编码。
  • 返回值:此方法返回写入的八位字节数。 如果缓冲区中没有足够的空间来容纳整个字符串,它将写入字符串的一部分。

9.2.1. 示例

buf = new Buffer(256);
len = buf.write("Simply Easy Learning");
console.log("Octets written : "+  len);

执行上述程序时,会产生以下结果:

Octets written : 20

9.3. 从缓冲区读书

  • 语法:buf.toString([encoding][, start][, end])
  • 参数:
    • encoding :要使用的编码。 ‘utf8’是默认编码。
    • start :开始读取的开始索引,默认为0。
    • end :结束读取的结束索引,默认为完整缓冲区。
  • 返回值:此方法解码并返回使用指定字符集编码编码的缓冲区数据中的字符串。

9.3.1. 示例

buf = new Buffer(26);
for (var i = 0 ; i < 26 ; i++) {
  buf[i] = i + 97;
}
console.log( buf.toString('ascii'));       // outputs: abcdefghijklmnopqrstuvwxyz
console.log( buf.toString('ascii',0,5));   // outputs: abcde
console.log( buf.toString('utf8',0,5));    // outputs: abcde
console.log( buf.toString(undefined,0,5)); // encoding defaults to 'utf8', outputs abcde

执行上述程序时,会产生以下结果:

abcdefghijklmnopqrstuvwxyz
abcde
abcde
abcde

9.4. 将Buffer转换为JSON

  • 语法:buf.toJSON()
  • 返回值:此方法返回Buffer实例的JSON表示形式。

9.4.1. 示例

var buf = new Buffer('Simply Easy Learning');
var json = buf.toJSON(buf);
console.log(json);

执行上述程序时,会产生以下结果:

{ type: 'Buffer',
   data: 
   [ 
      83,
      105,
      109,
      112,
      108,
      121,
      32,
      69,
      97,
      115,
      121,
      32,
      76,
      101,
      97,
      114,
      110,
      105,
      110,
      103 
   ]
}

9.5. 连接缓冲区

  • 语法:Buffer.concat(list[, totalLength])
  • 参数:
    • list :要连接的Buffer对象的Array列表。
    • totalLength :这是连接时缓冲区的总长度。
  • 返回值:此方法返回Buffer实例。

9.5.1. 示例

var buffer1 = new Buffer('IoWiki ');
var buffer2 = new Buffer('Simply Easy Learning');
var buffer3 = Buffer.concat([buffer1,buffer2]);
console.log("buffer3 content: " + buffer3.toString());

执行上述程序时,会产生以下结果:buffer3 content: IoWiki Simply Easy Learning

9.6. 比较缓冲区

  • 语法:buf.compare(otherBuffer);
  • 参数:
    • otherBuffer – 这是另一个与buf 进行比较的buf
  • 返回值:返回一个数字,指示它是排在顺序之前还是之后,或者与排序顺序中的otherBuffer相同。

9.6.1. 示例

var buffer1 = new Buffer('ABC');
var buffer2 = new Buffer('ABCD');
var result = buffer1.compare(buffer2);
if(result < 0) {
   console.log(buffer1 +" comes before " + buffer2);
} else if(result === 0) {
   console.log(buffer1 +" is same as " + buffer2);
} else {
   console.log(buffer1 +" comes after " + buffer2);
}

执行上述程序时,会产生以下结果:ABC comes before ABCD

9.7. 复制缓冲区

  • 语法:buf.copy(targetBuffer[, targetStart][, sourceStart][, sourceEnd])
  • 参数:
    • targetBuffer – 缓冲区将被复制的缓冲区对象。
    • targetStart – Number,Optional,默认值:0
    • sourceStart – Number,Optional,默认值:0
    • sourceEnd – Number,Optional,默认值:buffer.length
  • 返回值:没有回报价值。 即使目标存储器区域与源重叠,也要将数据从此缓冲区的区域复制到目标缓冲区中的区域。 如果未定义,则targetStart和sourceStart参数默认为0,而sourceEnd默认为buffer.length。

9.7.1. 示例

var buffer1 = new Buffer('ABC');
//copy a buffer
var buffer2 = new Buffer(3);
buffer1.copy(buffer2);
console.log("buffer2 content: " + buffer2.toString());

执行上述程序时,会产生以下结果:buffer2 content: ABC

9.8. 切片缓冲液

  • 语法:buf.slice([start][, end])
  • 参数:
    • start – Number,Optional,默认值:0
    • end – Number,Optional,默认值:buffer.length
  • 返回值:返回一个新的缓冲区,该缓冲区引用与旧的内存相同的内存,但是由start(默认为0)和end(默认为buffer.length)索引进行偏移和裁剪。 负索引从缓冲区的末尾开始。

9.8.1. 示例

var buffer1 = new Buffer('IoWiki');
//slicing a buffer
var buffer2 = buffer1.slice(0,9);
console.log("buffer2 content: " + buffer2.toString());

执行上述程序时,会产生以下结果:buffer2 content: Tutorials

9.9. 缓冲长度

  • 语法:buf.length;
  • 返回值:以字节为单位返回缓冲区的大小。

9.9.1. 示例

var buffer = new Buffer('IoWiki');
//length of the buffer
console.log("buffer length: " + buffer.length);

执行上述程序时,会产生以下结果:buffer length: 14

9.10. 方法参考

以下是Node.js中提供的Buffers模块的参考。 有关更多详细信息,请参阅官方文档。

No. 方法和描述
1 new Buffer(size) 分配大小为八位字节的新缓冲区。 请注意,大小不得超过kMaxLength。 否则,将抛出RangeError。
2 new Buffer(buffer) 将传递的缓冲区数据复制到新的Buffer实例上。
3 new Buffer(str[, encoding]) 分配包含给定str的新缓冲区。 编码默认为’utf8’。
4 buf.length 以字节为单位返回缓冲区的大小。 请注意,这不一定是内容的大小。 length是指为缓冲区对象分配的内存量。 当缓冲区的内容发生变化时,它不会改变。
5 buf.write(string[, offset][, length][, encoding]) 使用给定的编码将字符串写入offset处的缓冲区。 offset默认为0,编码默认为’utf8’。 length是要写入的字节数。 返回写入的八位字节数。
6 buf.writeUIntLE(value, offset, byteLength[, noAssert]) 在指定的偏移量和byteLength处将值写入缓冲区。 支持高达48位的精度。 将noAssert设置为true可跳过值和偏移的验证。 默认为false。
7 buf.writeUIntBE(value, offset, byteLength[, noAssert]) 在指定的偏移量和byteLength处将值写入缓冲区。 支持高达48位的精度。 将noAssert设置为true可跳过值和偏移的验证。 默认为false。
8 buf.writeIntLE(value, offset, byteLength[, noAssert]) 在指定的偏移量和byteLength处将值写入缓冲区。 支持高达48位的精度。 将noAssert设置为true可跳过值和偏移的验证。 默认为false。
9 buf.writeIntBE(value, offset, byteLength[, noAssert]) 在指定的偏移量和byteLength处将值写入缓冲区。 支持高达48位的精度。 将noAssert设置为true可跳过值和偏移的验证。 默认为false。
10 buf.readUIntLE(offset, byteLength[, noAssert]) 所有数字读取方法的通用版本。 支持高达48位的精度。 将noAssert设置为true可跳过offset的验证。 这意味着偏移量可能超出缓冲区的末尾。 默认为false。
11 buf.readUIntBE(offset, byteLength[, noAssert]) 所有数字读取方法的通用版本。 支持高达48位的精度。 将noAssert设置为true可跳过offset的验证。 这意味着偏移量可能超出缓冲区的末尾。 默认为false。
12 buf.readIntLE(offset, byteLength[, noAssert]) 所有数字读取方法的通用版本。 支持高达48位的精度。 将noAssert设置为true可跳过offset的验证。 这意味着偏移量可能超出缓冲区的末尾。 默认为false。
13 buf.readIntBE(offset, byteLength[, noAssert]) 所有数字读取方法的通用版本。 支持高达48位的精度。 将noAssert设置为true可跳过offset的验证。 这意味着偏移量可能超出缓冲区的末尾。 默认为false。
14 buf.toString([encoding][, start][, end]) 从使用指定字符集编码编码的缓冲区数据中解码并返回一个字符串。
15 buf.toJSON() 返回Buffer实例的JSON表示形式。 在对Buffer实例进行字符串化时,JSON.stringify会隐式调用此函数。
16 buf[index] 获取并设置索引处的八位字节。 这些值指的是单个字节,因此合法范围介于0x00和0xFF十六进制之间或0到255之间。
17 buf.equals(otherBuffer) 如果此缓冲区和otherBuffer具有相同的字节,则返回布尔值。
18 buf.compare(otherBuffer) 返回一个数字,指示此缓冲区是在排序顺序之前还是之后,或者与otherBuffer相同。
19 buf.copy(targetBuffer[, targetStart][, sourceStart][, sourceEnd]) 即使目标存储器区域与源重叠,也要将数据从此缓冲区的区域复制到目标缓冲区中的区域。 如果未定义,则targetStart和sourceStart参数默认为0,而sourceEnd默认为buffer.length。
20 buf.slice([start][, end]) 返回一个新的缓冲区,它引用与旧的相同的内存,但是偏移并由start(默认为0)和end(默认为buffer.length)索引进行裁剪。 负索引从缓冲区的末尾开始。
21 buf.readUInt8(offset[, noAssert]) 从指定偏移量的缓冲区中读取无符号8位整数。 将noAssert设置为true可跳过offset的验证。 这意味着偏移量可能超出缓冲区的末尾。 默认为false。
22 buf.readUInt16LE(offset[, noAssert]) 使用指定的endian格式从指定偏移量的缓冲区中读取无符号的16位整数。 将noAssert设置为true可跳过offset的验证。 这意味着偏移量可能超出缓冲区的末尾。 默认为false。
23 buf.readUInt16BE(offset[, noAssert]) 使用指定的endian格式从指定偏移量的缓冲区中读取无符号的16位整数。 将noAssert设置为true可跳过offset的验证。 这意味着偏移量可能超出缓冲区的末尾。 默认为false。
24 buf.readUInt32LE(offset[, noAssert]) 使用指定的endian格式从指定偏移量的缓冲区中读取无符号的32位整数。 将noAssert设置为true可跳过offset的验证。 这意味着偏移量可能超出缓冲区的末尾。 默认为false。
25 buf.readUInt32BE(offset[, noAssert]) 使用指定的endian格式从指定偏移量的缓冲区中读取无符号的32位整数。 将noAssert设置为true可跳过offset的验证。 这意味着偏移量可能超出缓冲区的末尾。 默认为false。
26 buf.readInt8(offset[, noAssert]) 从指定偏移量的缓冲区中读取带符号的8位整数。 将noAssert设置为true可跳过offset的验证。 这意味着偏移量可能超出缓冲区的末尾。 默认为false。
27 buf.readInt16LE(offset[, noAssert]) 使用指定的endian格式从指定偏移量的缓冲区读取带符号的16位整数。 将noAssert设置为true可跳过offset的验证。 这意味着偏移量可能超出缓冲区的末尾。 默认为false。
28 buf.readInt16BE(offset[, noAssert]) 使用指定的endian格式从指定偏移量的缓冲区读取带符号的16位整数。 将noAssert设置为true可跳过offset的验证。 这意味着偏移量可能超出缓冲区的末尾。 默认为false。
29 buf.readInt32LE(offset[, noAssert]) 使用指定的endian格式从指定偏移量的缓冲区中读取带符号的32位整数。 将noAssert设置为true可跳过offset的验证。 这意味着偏移量可能超出缓冲区的末尾。 默认为false。
30 buf.readInt32BE(offset[, noAssert]) 使用指定的endian格式从指定偏移量的缓冲区中读取带符号的32位整数。 将noAssert设置为true可跳过offset的验证。 这意味着偏移量可能超出缓冲区的末尾。 默认为false。
31 buf.readFloatLE(offset[, noAssert]) 使用指定的endian格式从指定偏移量的缓冲区中读取32位浮点数。 将noAssert设置为true可跳过offset的验证。 这意味着偏移量可能超出缓冲区的末尾。 默认为false。
32 buf.readFloatBE(offset[, noAssert]) 使用指定的endian格式从指定偏移量的缓冲区中读取32位浮点数。 将noAssert设置为true可跳过offset的验证。 这意味着偏移量可能超出缓冲区的末尾。 默认为false。
33 buf.readDoubleLE(offset[, noAssert]) 使用指定的endian格式从指定偏移量的缓冲区读取64位double。 将noAssert设置为true可跳过offset的验证。 这意味着偏移量可能超出缓冲区的末尾。 默认为false。
34 buf.readDoubleBE(offset[, noAssert]) 使用指定的endian格式从指定偏移量的缓冲区读取64位double。 将noAssert设置为true可跳过offset的验证。 这意味着偏移量可能超出缓冲区的末尾。 默认为false。
35 buf.writeUInt8(value, offset[, noAssert]) 将值写入指定偏移量的缓冲区。 请注意,该值必须是有效的无符号8位整数。 将noAssert设置为true可跳过值和偏移的验证。 这意味着该值对于特定函数可能太大,并且偏移量可能超出缓冲区的末尾,导致值被静默删除。 除非您确定其正确性,否则不应使用它。 默认为false。
36 buf.writeUInt16LE(value, offset[, noAssert]) 使用指定的endian格式将值写入指定偏移量的缓冲区。 请注意,该值必须是有效的无符号16位整数。 将noAssert设置为true可跳过值和偏移的验证。 这意味着该值对于特定函数可能太大,并且偏移量可能超出缓冲区的末尾,导致值被静默删除。 除非您确定正确性,否则不应使用它。 默认为false。
37 buf.writeUInt16BE(value, offset[, noAssert]) 使用指定的endian格式将值写入指定偏移量的缓冲区。 请注意,该值必须是有效的无符号16位整数。 将noAssert设置为true可跳过值和偏移的验证。 这意味着该值对于特定函数可能太大,并且偏移量可能超出缓冲区的末尾,导致值被静默删除。 除非您确定其正确性,否则不应使用它。 默认为false。
38 buf.writeUInt32LE(value, offset[, noAssert]) 使用指定的endian格式将值写入指定偏移量的缓冲区。 请注意,该值必须是有效的无符号32位整数。 将noAssert设置为true可跳过值和偏移的验证。 这意味着该值对于特定函数可能太大,并且偏移量可能超出缓冲区的末尾,导致值被静默删除。 除非您确定其正确性,否则不应使用它。 默认为false。
39 buf.writeUInt32BE(value, offset[, noAssert]) 使用指定的endian格式将值写入指定偏移量的缓冲区。 请注意,该值必须是有效的无符号32位整数。 将noAssert设置为true可跳过值和偏移的验证。 这意味着该值对于特定函数可能太大,并且偏移量可能超出缓冲区的末尾,导致值被静默删除。 除非您确定其正确性,否则不应使用它。 默认为false。
40 buf.writeInt8(value, offset[, noAssert]) 使用指定的endian格式将值写入指定偏移量的缓冲区。 请注意,该值必须是有效的带符号8位整数。 将noAssert设置为true可跳过值和偏移的验证。 这意味着该值对于特定函数可能太大,并且偏移量可能超出缓冲区的末尾,导致值被静默删除。 除非您确定其正确性,否则不应使用它。 默认为false。
41 buf.writeInt16LE(value, offset[, noAssert]) 使用指定的endian格式将值写入指定偏移量的缓冲区。 请注意,该值必须是有效的带符号16位整数。 将noAssert设置为true可跳过值和偏移的验证。 这意味着该值对于特定函数可能太大,并且偏移量可能超出缓冲区的末尾,导致值被静默删除。 除非您确定其正确性,否则不应使用它。 默认为false。
42 buf.writeInt16BE(value, offset[, noAssert]) 使用指定的endian格式将值写入指定偏移量的缓冲区。 请注意,该值必须是有效的带符号16位整数。 将noAssert设置为true可跳过值和偏移的验证。 这意味着该值对于特定函数可能太大,并且偏移量可能超出缓冲区的末尾,导致值被静默删除。 除非您确定其正确性,否则不应使用它。 默认为false。
43 buf.writeInt32LE(value, offset[, noAssert]) 使用指定的endian格式将值写入指定偏移量的缓冲区。 请注意,该值必须是有效的带符号32位整数。 将noAssert设置为true可跳过值和偏移的验证。 这意味着该值对于特定函数可能太大,并且偏移量可能超出缓冲区的末尾,导致值被静默删除。 除非您确定其正确性,否则不应使用它。 默认为false。
44 buf.writeInt32BE(value, offset[, noAssert]) 使用指定的endian格式将值写入指定偏移量的缓冲区。 请注意,该值必须是有效的带符号32位整数。 将noAssert设置为true可跳过值和偏移的验证。 这意味着该值对于特定函数可能太大,并且偏移量可能超出缓冲区的末尾,导致值被静默删除。 除非您确定正确性,否则不应使用它。 默认为false。
45 buf.writeFloatLE(value, offset[, noAssert]) 使用指定的endian格式将值写入指定偏移量的缓冲区。 请注意,该值必须是有效的32位浮点数。 将noAssert设置为true可跳过值和偏移的验证。 这意味着该值对于特定函数可能太大,并且偏移量可能超出缓冲区的末尾,导致值被静默删除。 除非您确定其正确性,否则不应使用它。 默认为false。
46 buf.writeFloatBE(value, offset[, noAssert]) 使用指定的endian格式将值写入指定偏移量的缓冲区。 注意,value必须是有效的32位浮点数。 将noAssert设置为true可跳过值和偏移的验证。 这意味着该值对于特定函数可能太大,并且偏移量可能超出缓冲区的末尾,导致值被静默删除。 除非您确定其正确性,否则不应使用它。 默认为false。
47 buf.writeDoubleLE(value, offset[, noAssert]) 使用指定的endian格式将值写入指定偏移量的缓冲区。 注意,value必须是有效的64位double。 将noAssert设置为true可跳过值和偏移的验证。 这意味着对于特定函数,值可能太大,并且偏移量可能超出缓冲区的末尾,从而导致值被静默删除。 除非您确定其正确性,否则不应使用它。 默认为false。
48 buf.writeDoubleBE(value, offset[, noAssert]) 使用指定的endian格式将值写入指定偏移量的缓冲区。 注意,value必须是有效的64位double。 将noAssert设置为true可跳过值和偏移的验证。 这意味着该值对于特定函数可能太大,并且偏移量可能超出缓冲区的末尾,导致值被静默删除。 除非您确定其正确性,否则不应使用它。 默认为false。
49 buf.fill(value[, offset][, end]) 使用指定的值填充缓冲区。 如果没有给出偏移量(默认为0)和结束(默认为buffer.length),它将填充整个缓冲区。

9.11. 类方法

No. 方法和描述
1 Buffer.isEncoding(encoding) 如果编码是有效的编码参数,则返回true,否则返回false。
2 Buffer.isBuffer(obj) 测试obj是否为Buffer。
3 Buffer.byteLength(string[, encoding]) 给出字符串的实际字节长度。 编码默认为’utf8’。 它与String.prototype.length不同,因为String.prototype.length返回字符串中的字符数。
4 Buffer.concat(list[, totalLength]) 返回一个缓冲区,它是将列表中的所有缓冲区连接在一起的结果。
5 Buffer.compare(buf1, buf2) 与buf1.compare(buf2)相同。 用于排序缓冲区数组。
下一节:流是允许您以连续方式从源读取数据或将数据写入目标的对象。