Node.js 中文手册

中文翻译:www.nodecn.org 转载请注明出处

目录


缓冲区

纯 Javascript 能够很好地支持 Unicode,却不擅长处理二进制数据。与 TCP 数据流或文件系统打交道时,必须处理字节流。Node 有多种方式来操作、建立、消耗字节流。

原始数据存储在 Buffer 类的实例中。一个 Buffer 类似于一个整数数组,但它对应于 V8 堆内存之外的一块原始内存。Buffer 不能调整大小。

Buffer 对象是全局的。

Buffer 和 Javascript 字符串对象之间的转换需要显式地调用编码方法来完成。以下是几种不同的字符串编码:

new Buffer(size)

分配一个 size 字节大小的缓冲区。

new Buffer(array)

使用 array 中的字节数据来分配缓冲区。

new Buffer(str, encoding='utf8')

分配一个包含给定字符串 str 的缓冲区。

buffer.write(string, offset=0, encoding='utf8')

使用指定的编码向缓冲区偏移 offset 处写入字符串 string。返回写入的字节数。如果 buffer 中没有足够的空间来存储整个字符串,字符串的一部分将被写入。使用 'utf8' 编码时,该方法不会截断字符。

示例:向缓冲区写入一个 utf-8 字符串并打印

buf = new Buffer(256);
len = buf.write('\u00bd + \u00bc = \u00be', 0);
console.log(len + " bytes: " + buf.toString('utf8', 0, len));

// 12 bytes: ½ + ¼ = ¾

buffer.toString(encoding, start=0, end=buffer.length)

对缓冲区中从位置 startend、以 encoding 编码的数据进行解码,并返回该字符串。

参考上文的 buffer.write() 示例。

buffer[index]

获取或设置在位置 index 处的字节。该值是不可分割的字节,所以合法的范围是十六进制的 0x000xFF,或十进制的 0255

示例:复制一个 ASCII 字符串到缓冲区,每次一个字节

str = "node.js";
buf = new Buffer(str.length);

for (var i = 0; i < str.length ; i++) {
  buf[i] = str.charCodeAt(i);
}

console.log(buf);

// node.js

Buffer.isBuffer(obj)

测试 obj 是否为一个 Buffer 实例。

Buffer.byteLength(string, encoding='utf8')

返回一个字符串的实际字节长度。这跟 String.prototype.length 不太一样,因为 String.prototype.length 返回的是字符串的字符长度。

例如:

str = '\u00bd + \u00bc = \u00be';

console.log(str + ": " + str.length + " characters, " +
  Buffer.byteLength(str, 'utf8') + " bytes");

// ½ + ¼ = ¾: 9 characters, 12 bytes

buffer.length

以字节数表示的缓冲区大小。请注意,这不一定是内容的大小。length 指的是给缓冲区分配的内存大小。缓冲区的内容发生改变时,它并不会改变。

buf = new Buffer(1234);

console.log(buf.length);
buf.write("some string", "ascii", 0);
console.log(buf.length);

// 1234
// 1234

buffer.copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)

在缓冲区之间使用 memcpy() 进行复制。

示例:建立两个缓冲区,然后复制 buf1 第 16 到 19 字节的数据到 buf2 的第 8 字节处。

buf1 = new Buffer(26);
buf2 = new Buffer(26);

for (var i = 0 ; i < 26 ; i++) {
  buf1[i] = i + 97; // 97 is ASCII a
  buf2[i] = 33; // ASCII !
}

buf1.copy(buf2, 8, 16, 20);
console.log(buf2.toString('ascii', 0, 25));

// !!!!!!!!qrst!!!!!!!!!!!!!

buffer.slice(start, end=buffer.length)

返回一个新的缓冲区,它和旧缓冲区指向同一块内存,但是从索引 startend 的位置剪裁。

修改新的缓冲区将修改旧缓冲区的内存!

示例:建立一个包含 ASCII 字母表的缓冲区,取得一个切片,然后从原来的缓冲区修改一个字节。

var buf1 = new Buffer(26);

for (var i = 0 ; i < 26 ; i++) {
  buf1[i] = i + 97; // 97 is ASCII a
}

var buf2 = buf1.slice(0, 3);
console.log(buf2.toString('ascii', 0, buf2.length));
buf1[0] = 33;
console.log(buf2.toString('ascii', 0, buf2.length));

// abc
// !bc