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;
});
// 输出: <Buffer 01 02 03 04 05>
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());
网友评论