Node.js Buffer(缓冲区)
参考https://www.runoob.com/nodejs/nodejs-buffer.html
- JavaScript本身只有字符串数据类型,没有二进制数据类型;
- 处理像TCP流或文件流时,必须用到二进制数据,因此使用Node.js中的Buffer类,用于创建一个缓冲区(缓存区)来存放二进制数据。
Buffer类时Node.js的一个核心库。一个Buffer对象类似于一个整数数组,但它对应于V8引擎的堆内存之外的一块原始内存(原生内存/堆外内存/直接内存)。
建议直接使用Buffer.from()接口去创建Buffer对象。
Buffer与字符编码
Buffer实例一般用于表示编码字符的序列,比如UTF-8、UCS2、Base64或16进制编码的数据。通过显式的字符编码,就可以实现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(ucs2):2或4个字节,小字节序编码的Unicode字符,支持代理对(U+10000至U+10FFFF);
- base64:Base64编码;
- latin1(binary):一种把Buffer编码成一字节字符串的编码方式;
- hex:将每个字节编码为两个16进制字符。
创建Buffer类实例
7种方法创建Buffer实例:
- Buffer.alloc(size[, fill[, encoding]]): 返回一个指定大小的 Buffer 实例,如果没有设置 fill,则默认填满 0
- Buffer.allocUnsafe(size): 返回一个指定大小的 Buffer 实例,但是它不会被初始化,所以它可能包含敏感的数据
- Buffer.allocUnsafeSlow(size)
- 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(默认用0填充)
const buf1 = Buffer.alloc(10);
// 创建一个长度为10,且用0x1填充的buffer
const buf2 = Buffer.alloc(10, 1);
// 创建一个长度为10,且未初始化的buffer
// 这个方法比Buffer.alloc()快
// 但是返回的实例种可能包含旧数据
// 因此需要用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('test');
// 创建一个包含Latin-1字节[0x74, 0xe9, 0x73, 0x74]的buffer
cosnt buf6 = Buffer.from('test', 'latin1');
写入缓冲区
语法
buffer.write(string[,offset[,length]][,encoding])
参数
- string:写入缓冲区的字符串;
- offset:缓冲区开始写入的索引值,默认为0;
- length:写入的字节数,默认为buffer.length;
- encoding:使用的编码,默认为‘utf-8’。
如果buffer的空间不足,则只会写入一部分。
返回值
返回实际写入的空间大小。
实例
var buf = Buffer.alloc(256);
var len = buf.write('test');
console.log('写入字节数:'+len);
结果:
写入字节数:4
从缓冲区读取数据
语法
buf.toString([encoding[,start[,end]]])
- encoding:使用的编码,默认为‘tuf-8’;
- start:从指定索引位置开始读取,默认为0;
- end:从指定索引位置结束读取,默认为缓冲区的末尾。
返回值
返回指定编码的字符串。
var buf = Buffer.alloc(26);
for( var i=0; i<26; i++){
buf[i] = i+97;
}
console.log(buf.toString('ascii'));//使用'ascii'编码输出所有字符
console.log(buf.toString('ascii', 0, 5));//使用'ascii'编码输出前5个字符
console.log(buf.toString('utf8', 0, 5));//使用'utf8'编码输出前5个字符
console.log(buf.toString(undefined, 0, 5));// 使用默认的'utf8'编码输出前5个字符
结果:
abcdefghijklmnopqrstuvwxyz
abcde
abcde
abcde
将Buffer对象转为JSON对象
语法
buf.toJSON()
效果等同JSON.stringfy(),其实是JSON.stringfy()调用了buf.toJSON()。
返回值
返回JSON化的JSON对象。
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);
结果:
{"type":"Buffer","data":[1,2,3,4,5]}
<Buffer 01 02 03 04 05>
缓冲区合并
语法
Buffer.concat(list[,totalLength])
- list:用于合并的Buffer对象数组列表。
- totalLength:指定合并后Buffer对象的总长度,默认为两个对象空间的总长度(小于默认值时会丢弃)。
返回值
返回一个最终合并的新Buffer对象。
var buf1 = Buffer.from('菜鸟教程');
var buf2 = Buffer.from('www.runoob.com');
var buf3 = Buffer.concat([buf1, buf2]);
console.log(buf3.toString());
结果:
菜鸟教程www.runoob.com
缓冲区比较
语法
buf.compare(otherBuffer);
- otherBuffer:与buf对象比较的另一个Buffer对象。
返回值
返回一个数字,类似于C语言中的strcmp()函数。0表示相同。
var buf1 = Buffer.from('ABC');
var buf2 = Buffer.from('ABCD');
var result = buf1.compare(buf2);
console.log(result);
结果:
-1
拷贝缓冲区
语法
buf.copy(targetBuffer[, targetStart[, sourceStart[, sourceEnd]]])
- targetBuffer:目标Buffer对象;
- targetStart:目标Buffer对象的开始位置(索引),默认为0;
- sourceStart:从何处(索引)开始拷贝,默认为0;
- sourceEnd:到何处拷贝截至,默认为整个targetBuffer对象的长度。
返回值
无
var buf1 = Buffer.from('ABcdEFG');
var buf2 = Buffer.from('CD');
buf2.copy(buf1, 2);
console.log(buf1.toString());
结果:
ABCDEFG
缓冲区裁剪
语法
buf.slice([start[, end]])
- start:起始位置,默认为0;
- end:结束位置,默认为buf.length,左闭右开。
返回值
返回一个新的Buffer对象,和旧的指向同一块内存,只是长度不同。
var buf1 = Buffer.from('abCDEFG');
var buf2 = buf1.slice(2, 7);
console.log(buf2.toString());
结果:
CDEFG
缓冲区长度
语法
buf.length;
返回值
返回Buffer对象所占据的内存长度。
var buffer = Buffer.from('www.runoob.com');
// 缓冲区长度
console.log("buffer length: " + buffer.length);
结果:
buffer length: 14