node 学习笔记 - Buffer

Buffer 是 node 用于处理各种数据流或文件系统数据的,而且一个 Buffer 实例大小是不可变的。
Buffer 是一个全局类,不需要 require('buffer') 引入。

一开始以为 Buffer 只是很小的一部分,但是学习了下才发现任何数据处理比如文件、tcp流等,都是基于 Buffer 几乎遍布在整个 node 内,所以 Buffer 才是为数不多的全局模块。

创建 Buffer

有多种方法实例化 Buffer。

new Buffer(array) 通过数组创建
new Buffer(buffer) 通过一个实例化的buffer创建
new Buffer(size) 通过给定数字创建
new Buffer(str[, encoding]) 通过字符串创建

创建一个空的 Buffer 实例后,你可以使用 buf.fill(0) 来做初始化数据填充。
通过字符串创建,可以指定 encoding 编码,编码是 ‘ascii’,’utf8’, ‘ucs2’, ‘base64’, ‘binary’, ‘hex’ 其中之一。
但是遗憾的是不支持 ‘gbk’, ‘gb2312’ 编码。

1
2
3
4
5
6
7
8
var buf = new Buffer('\u4f00'); // 伀

console.log('\u4f00 \u4f01'); // 伀 企
console.log(buf); // <Buffer e4 bc 80>

console.log(buf.toString()); // 伀
buf[2] = 0x81; // 修改16进制数据,变成了 <Buffer e4 bc 81>
console.log(buf.toString()); // 企

所以哪怕是字符串,其实在 Buffer 依然是一组16进制数据,也就是官方文档上说的 octet streams (字节流)。
其实 Buffer 本质就是对 Uint8Array 的封装。

Buffer 修改

Buffer 的方法还是比较多的,我就简单记录几个看起来常用的吧,反正我也没用过。

1
2
3
4
5
6
7
8
9
10
11
12
var buf = new Buffer('1234');

buf[2] = 97; // 修改索引为 2 的值, 97 是 a 的 ascii
console.log(buf.toString()); // 12a4

buf.write('xx', 2); // 修改索引 2 开始的值
console.log(buf.toString()); // 12xx

buf[5] = 97; // 修改索引为 5 的值, 不成功,也不报错
console.log(buf.toString()); // 12xx

buf.write('xx', 5); // 超出 buf 实例范围,抛出 RangeError

这样看来,直接 write 方法方便,而且可以直接用字符串修改,但是要注意范围,而通过索引修改则不会报错。

Buffer 复制

语法
buf.copy(targetBuffer[, targetStart][, sourceStart][, sourceEnd])

1
2
3
4
5
6
7
8
var buf1 = new Buffer('12345');
var buf2 = new Buffer('-----');

buf1.copy(buf2, 1, 1, 4); // 复制局部
console.log(buf2.toString()); // -234-

buf1.copy(buf2); // 复制全部
console.log(buf2.toString()); // 1234

Buffer 合并

语法
Buffer.concat(list[, totalLength])

1
2
3
4
5
6
7
8
9
var buf1 = new Buffer('123');
var buf2 = new Buffer('456');
var buf3 = new Buffer('789');

var buf4 = Buffer.concat([buf1, buf2, buf3], 5); // 只能保留前5个
console.log(buf4.toString()); // 12345

var buf4 = Buffer.concat([buf1, buf2, buf3]); // 全部合并
console.log(buf4.toString()); // 123456789

其他属性方法

还有N多方法,不过这里有一个要特殊介绍下。

Buffer.byteLength(string[, encoding])

1
2
console.log('呵呵'.length); // 2
console.log(Buffer.byteLength('呵呵', 'utf8')); // 6

js 是对 Unicode 友好的,所以一个英文字符或者是一个中文字符,都计算为一个字符。
而保存数据或者 tcp 之类的通信,都是基于字节的,所以必须得到真正的字节才行,byteLength 这是根据编码计算出真正的字节数。

这些基本方法掌握就差不多,其他属性方法等用到时再查了。