Buffer
Buffer 不占用V8 内存
是在node的c++ 层面实现内存的申请的
采用 slab 分配机制 动态内存管理机制
简述 slab机制
1.full 完全分配机制
2.partial 部分分配机制
3.empty 没有被分配机制
Buffer 对象分类
node 以8KB 区分是大对象还是小对象
大对象直接分配一个SlowBuffer对象作为slab单元
小对象 会预先分配一个SlowBuffer对象 然后插入 如果后续的SlowBuffer 还有剩余空间且足够 小对象时用 则存入。否则新建一个新的SlowBuffer
使用场景
基本使用
let str = '这是一个简单的字符串';
let buf = new Buffer(str);
// 返回的是16进制的 0---256的数值
//buffer 收 array 影响比较大
console.log(buf);
// <Buffer e8 bf 99 e6 98 af e4 b8 80 e4 b8 aa e7 ae 80 e5 8d 95 e7 9a 84 e5 ad 97 e7 ac a6 e4 b8 b2>
console.log(buf.length);
// 30
console.log(buf[0]);
// 322
let buf1 = new Buffer(100);
buf1[31] = 222;
buf1[32] = -22;
buf1[33] = 3.33;
console.log(buf1); //<Buffer 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 de ea 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... >
console.log(buf1[31]); //222
console.log(buf1[32]); //256+ -22 = 234
console.log(buf1[33]); //3.33 == 3
console.log(buf1.length); // 100
Buffer 与 自字符串之间的转换
支持的编码格式
ASCII
UTF-8
UTF-16/USC-2
Base64
Binary
Hex
let str2 = buf.toString('utf8', 0, 30);
console.log(str2);
Buffer 拼接
英文问题 但是中文是宽子节 utf 下一个汉子占三个字节
console.log(new Buffer('床前明月光疑是地上霜举头望明月低头思故乡'));
var fs = require('fs');
// highWaterMark 限定buffer刻度长度为11
// highWaterMark 对buffer 性能的影响
// 1。highWaterMark的数值对buffer的内存分配和使用有一定的影响
// 2. highWaterMark的数值过小对 buffer内的调用次数增多,性能下降
var rs = fs.createReadStream('test.md', {highWaterMark: 11});
var data = '';
rs.on('data', function(chunk) {
//这句话隐藏语句 默认将buffer转化为字符串 data = data.toString() + chunk.toString();
data += chunk;
})
rs.on('end', function() {
console.log(data); //床前���月光,疑是地��霜。举���望明月,低头��故乡。
})
var rs = fs.createReadStream('test.md', {highWaterMark: 11});
rs.setEncoding('utf8'); //设置可读流之后 正常输出
var data = '';
rs.on('data', function(chunk) {
//这句话隐藏语句 默认将buffer转化为字符串 data = data.toString() + chunk.toString();
data += chunk;
})
rs.on('end', function() {
console.log(data); //床前明月光,疑是地上霜。举头望明月,低头思故乡。
})
setEncoding的内部实现 decoder 来自于string_decoder模块的StringDecoder的实例对象
var StringDecoder = require('string_decoder').StringDecoder;
var decoder = StringDecoder('utf8');
var buff1 = new Buffer([oxE5.....])
console.log(decoder.write(buff1)); //床前明 月字的两个字节保存 给到下面的一个字节
var buff2 = new Buffer([oxE5.....])
console.log(decoder.write(buff2));//月光,疑
//前面说过 一般是11个字符 但是 月 这个字 并没有被分开。是因为祝输出了前9个字符。然后两个保存到了 第二个实例中。
正确的拼接Buffer
将小对象合成一个大对象。 然后用iconv-lite这一类模块转化
var chunks = [];
var size = 0;
rs.on('data', function(chunk) {
chunks.push(chunk);
size += chunk.length;
});
rs.on('end', function () {
var buf = Buffer.concat(chunks, size);
var str = iconv.decode(buf, 'utf8');
console.log(str);
})
Buffer 与 性能
字符串转buffer 提高传输速率 提高网路吞吐率