Nodejs Buffer

Buffer用于存储原始数据,可以让Nodejs处理二进制数据。
Nodejs中处理I/O操作就可能用到Buffer。
原始数据存储在Buffer类的实例中,一个Buffer类似一个数组,对应于V8堆内存外的一块原始内存。

Buffer与字符编码

Buffer 实例一般用于表示编码字符的序列,比如 UTF-8 、 UCS2 、 Base64 、或十六进制编码的数据。 通过使用显式的字符编码,就可以在 Buffer 实例与普通的 JavaScript 字符串之间进行相互转换。

const buf = Buffer.from('runoob', 'ascii');

// 输出 72756e6f6f62
console.log(buf.toString('hex'));

// 输出 cnVub29i
console.log(buf.toString('base64'));

Node.js 目前支持的字符编码包括:

  • ascii - 仅支持 7 位 ASCII 数据。如果设置去掉高位的话,这种编码是非常快的。
  • utf8 - 多字节编码的 Unicode 字符。许多网页和其他文档格式都使用 UTF-8 。
  • utf16le - 2 或 4 个字节,小字节序编码的 Unicode 字符。支持代理对(U+10000 至 U+10FFFF)。
  • ucs2 - utf16le 的别名。
  • base64 - Base64 编码。
  • latin1 - 一种把 Buffer 编码成一字节编码的字符串的方式。
  • binary - latin1 的别名。
  • hex - 将每个字节编码为两个十六进制字符。

创建Buffer类

有以下的API用来创建Buffer类

  • Buffer.alloc(size[, fill[, encoding]]):返回一个指定大小的Buffer实例,如果没有设置fill,默认填满0.
  • Buffer.allocUnsafe(size):返回一个指定大小的Buffer实例,不过不会被初始化,所以可能包含敏感数据,通过buf.fill(0)将这个Buffer初始化为零。
    .alloc()会对分配的空间进行填充,保证新空间不会包含以前的数据,而.allocUnsafe()不会填充,所以更快。但是.allocUnsafe()后立即fill(),效果就和.alloc()一样,但是效率略差。
  • Buffer.from(array):返回一个被array值初始化的新Buffer实例(传入的array元素只能是数字,不然自动被0覆盖)
  • Buffer.from(arrayBuffer[, byteOffset[, length]]):返回一个新建的与给定ArrayBuffer共享同一内存的Buffer。
  • Buffer.from(buffer):复制传入的Buffer实例的数据,返回一个新的Buffer实例。
  • Buffer.from(string[, encoding]):返回一个被string值初始化的新Buffer实例。
// 创建一个长度为 10、且用 0 填充的 Buffer。
const buf1 = Buffer.alloc(10);

// 创建一个长度为 10、且用 0x1 填充的 Buffer。 
const buf2 = Buffer.alloc(10, 1);

// 创建一个长度为 10、且未初始化的 Buffer。
// 这个方法比调用 Buffer.alloc() 更快,
// 但返回的 Buffer 实例可能包含旧数据,
// 因此需要使用 fill() 或 write() 重写。
const buf3 = Buffer.allocUnsafe(10);

// 创建一个包含 [0x1, 0x2, 0x3] 的 Buffer。
const buf4 = Buffer.from([1, 2, 3]);

// 创建一个包含 UTF-8 字节 [0x74, 0xc3, 0xa9, 0x73, 0x74] 的 Buffer。
const buf5 = Buffer.from('tést');

// 创建一个包含 Latin-1 字节 [0x74, 0xe9, 0x73, 0x74] 的 Buffer。
const buf6 = Buffer.from('tést', 'latin1');

写入缓冲区

写入语法

buf.write(string[, offset[, length]][, encoding])
  • string - 写入缓冲区的字符串
  • offset - 缓冲区开始写入的索引值,默认0
  • length - 写入的字节数,默认buffer.length
  • encoding - 使用的编码,默认utf8
    根据 encoding 的字符编码写入 string 到 buf 中的 offset 位置。 length 参数是写入的字节数。 如果 buf 没有足够的空间保存整个字符串,则只会写入 string 的一部分。 只部分解码的字符不会被写入。
buf = Buffer.alloc(256);
len = buf.write("www.runoob.com");

console.log("写入字节数 : "+  len);

// 写入字节数14

读取数据

buf.toString([encoding[, start[, end]]])
  • encoding - 使用的编码。默认为 'utf8' 。
  • start - 指定开始读取的索引位置,默认为 0。
  • end - 结束位置,默认为缓冲区的末尾。
buf = Buffer.alloc(26);
for (var i = 0 ; i < 26 ; i++) {
  buf[i] = i + 97;
}

console.log( buf.toString('ascii'));       // 输出: abcdefghijklmnopqrstuvwxyz
console.log( buf.toString('ascii',0,5));   // 输出: abcde
console.log( buf.toString('utf8',0,5));    // 输出: abcde
console.log( buf.toString(undefined,0,5)); // 使用 'utf8' 编码, 并输出: abcde

Buffer转换为JSON对象

buf.toJSON()
当字符串化一个Buffer实例时,JSON.stringify()会隐式调用toJSON()

const buf = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5]);
const json = JSON.stringify(buf);

// 输出: {"type":"Buffer","data":[1,2,3,4,5]}
console.log(json);

const copy = JSON.parse(json, (key, value) => {
  return value && value.type === 'Buffer' ?
    Buffer.from(value.data) :
    value;
});

// 输出: 
console.log(copy);

缓冲区合并

Buffer.concat(list[, totalLength])

  • list - 用于合并的 Buffer 对象数组列表。
  • totalLength - 指定合并后Buffer对象的总长度。
var buffer1 = Buffer.from(('菜鸟教程'));
var buffer2 = Buffer.from(('www.runoob.com'));
var buffer3 = Buffer.concat([buffer1,buffer2]);
console.log("buffer3 内容: " + buffer3.toString());

缓冲区比较

buf.compare(otherBuffer)

  • otherBuffer - 与buf比较的另一个Buffer对象
    返回一个数字,表示buf在otherBuffer之前、之后或相同。
    是按位比较的,buffer1第一位比较buffer2的第一位,一位一位比较,大1小-1。
var buffer1 = Buffer.from('ABC');
var buffer2 = Buffer.from('ABCD');
var result = buffer1.compare(buffer2);

if(result < 0) {
   console.log(buffer1 + " 在 " + buffer2 + "之前");
}else if(result == 0){
   console.log(buffer1 + " 与 " + buffer2 + "相同");
}else {
   console.log(buffer1 + " 在 " + buffer2 + "之后");
}

拷贝缓冲区

buf.copy(targetBuffer[, targetStart[, sourceStart[, sourceEnd]]])
  • targetBuffer - 要拷贝的 Buffer 对象。
  • targetStart - 数字, 可选, 默认: 0
  • sourceStart - 数字, 可选, 默认: 0
  • sourceEnd - 数字, 可选, 默认: buffer.length
var buf1 = Buffer.from('abcdefghijkl');
var buf2 = Buffer.from('RUNOOB');

//将 buf2 插入到 buf1 指定位置上
buf2.copy(buf1, 2);
// BrunoobIJKL
console.log(buf1.toString());

缓冲区裁剪

buf.slice([start[, end]])

  • start - 数字, 可选, 默认: 0
  • end - 数字, 可选, 默认: buffer.length
    返回一个新的缓冲区,它和旧缓冲区指向同一块内存,但是从索引 start 到 end 的位置剪切。
    他们操作同一块内存区域。
var buffer1 = Buffer.from('runoob');
// 剪切缓冲区
var buffer2 = buffer1.slice(0,2);
// buffer2 content: ru
console.log("buffer2 content: " + buffer2.toString());

你可能感兴趣的:(Nodejs Buffer)