JS 善于处理字符串,但由于最初是被设置用来处理 HTML 文档的,因此并不善于处理二进制数据。JS中即没有字节类型,也没有结构化类型,甚至没有字节数组类型,只有数值类型和字符串类型。

由于Node是基于JS开发的,所以它可可以处理类似 HTTP 这样的文本协议,也可用它来与数据库通信、操作图像、上传文件。想想下,如果只是用字符串完成上诉任务将相当困难。

在早期Node通过将每个字节编码为文本字符来处理二进制数据,事实证明这种做法即浪费资源,速度有缓慢,还不可靠,并且难以控制。

为了处理类二进制数据,Node引入二进制缓冲区实现,该实现以 Buffer 伪类中的JS API形式暴露给外界。缓冲区的长度以字节为单位,并可以随机设置和获取缓冲区中的数据。

Buffer类的另一个特别之处是数据占用的内存并不是分配在 JavaScript VM内存堆中,这些对象不会被垃圾收集算法处理。它会占据一个不会被修改的永久内存地址,以避免因缓冲区内存的内存复制所造成的CPU浪费。

创建缓冲区

默认使用 UTF-8 编码格式的字符串来创建缓冲区

// 默认使用UTF-8编码格式创建缓冲区
var buf = new Buffer('hi');

// 指定编码格式的字符串创建缓冲区
var buf = new Buffer('hi', 'base64');

可被接收的编码格式与标识符

  • UTF-8 utf8
    一种变宽度的编码格式,可表示 Unicode 字符集中任意字符,是网络首选编码格式。默认使用utf8编码格式。
  • ASCII ascii
    仅适用于 ASCII 字符集
  • Base64 base64
    基于64个可打印的ASCII字符来表示二进制数据,Base64用于字符文档内嵌入可被转换成字符串的二进制数据,在需要时可完整无损地转换会原来的二进制格式。

若缓存区没有用具体内存初始化,则可通过制定容量大小来创建缓冲区,以备将来容纳数据。

// 指定长度创建新的缓冲区
var buf = new Buffer(1024);//创建长度为1024字节的缓冲区

在缓冲区中获取或设置数据

创建或获取缓冲区后,可使用 [] 操作符来访问缓冲区中某个字节。

$ node

# 创建缓冲区
> var buf = new Buffer('create a new buffer');

# 访问缓存区中第10个字节
> console.log(buffer[10]);
101

当创建一个已被初始化的缓冲区时,该缓冲区中包含的数据并非是0,而是一些随机值。

// 本地测试却输出的是0
> var buf = new Buffer(1024);
> buf[100]
0

可设置任意位置上的数据

# 将第100个位置上的数据设置为100
> buf[100] = 100

某些情况下,一些缓冲区操作并不会产生错误。

$ node
> var buf = new Buffer(1024)

# 若将缓冲区某位置设置为大于255的数,将会用256对该值取模,最终将取模结果赋值给该位置。
> buf[1] = 257
> buf[1]
1

# 若将缓冲区某位置设置为256则该位置实际是被赋值为0
> buf[2] = 256
> buf[2]
0

# 若将缓冲区某位置设置为小数则该位置仅会存储整数部分
> buf[3] = 100.123
> buf[3]
100

# 若尝试给超出缓冲区边界的位置赋值,则赋值操作将以失败告终,缓冲区不会发生变化。
> buf[1025]=100
> buf[1025]
undefined

通过查询缓冲区的length属性类获取其长度

> buf.length
1024

使用缓冲区长度迭代缓冲区内容,设置或获取每个字节。

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