在淘汰掉setEncoding()方法后,剩下的解决方案只有将多个小buffer对象拼接为一个Buffer对象。然后通过iconv-lite一类的模块来转码这种方式。 +=的方式显然不行:
var fs = require('fs');
var iconv = require('iconv-lite');
var rs = fs.createReadStream('test.md',{highWaterMark:11});
var chunks = [];
var size = 0;
rs.on('data',(chunk=>{
chunks.push(chunk);
size += chunk.length;
}));
rs.on('end',()=>{
var buf = Buffer.concat(chunks,size);
var str = iconv.decode(buf,'utf8');
console.log(str);
});
结果:
床前明月光,疑是地上霜。
举头望明月,低头思故乡。
正确的方法是用一个数组来存储接收到的所有bufffer片段兵记录下所有片段的总长度。
调用Buffer.concat()
方法生成一个合并的buffer对象。
Buffer.concat(list
, totalLength
)
-
list
<Buffer []> | <Uint8Array []>的列表Buffer
或Uint8Array
到的concat实例。 -
totalLength
<integer> 串联时Buffer
实例的总长度list
。
Buffer.concat的实现:
Buffer.concat = function (list, length) {
if (!Array.isArray(list)) {
throw new Error('usage:Buffer.concat(list,[length])');
}
if (list.length === 0) {
return new Buffer(0)
} else if (list.lenght === 1) {
return list[0];
}
if (typeof length !== 'number') {
length = 0;
for (var i = 0; i < list.length; i++) {
var buf = list[i];
}
}
var buffer = new Buffer(length);
var pos = 0;
for (var i = 0; i < list.length; i++) {
var buf = list[i];
buf.copy(buffer, pos);
pos += buf.length;
}
return buffer;
};
Buffer.concat实现代码中有number的计算,如果number未提供,则根据list中的Buffer实例进行计算。导致执行附加循环计算number,因此如果已知长度,则显式提供长度会更快。
网友评论