1、Buffer对象
buffer对象每个元素的值为16进制数(0-255之间),utf-8格式string转buffer对象时,汉字占3位,字母,符号占1位。
给buffer通过下标赋值为value,value大于255时会取value%256作为结果,小于0会追加256,直到值为0-255之间,有小数则会直接截断小数部分,然后取0-255之间整数值。
2、安全性
3、buffer内存分配
buffer对象使用内存为堆外内存,即在C++层面申请内存,javaScript层面分配内存。
Node为了分配申请好的内存,采用slab动态内存分配机制,每个slab为一块申请好的固定大小的内存单元(Buffer.poolSize=8*1024 8KB大小)。
slab有三种状态:
full :完全分配状态
partial:部分分配状态
empty:完全未分配状态
1、分配小buffer对象:如果指定buffer对象大小小于8KB,则为小对象分配。
申请固定分配单元slab,此时为empty状态。
new Buffer(1024) 分配1KB对象
new Buffer(3000) 再分配3000B对象
×如果先new Buffer(1024) 再 new Buffer(8*1024),当第二次分配对象不够存储在第一次预申请内存时,则会再申请一块slab内存单元然后存放第二个对象,所以第一个对象实际大小为1KB但却占用了8KB内存,可以解释实际内存使用量一般会大于申请量的现象。只有当每个slab中的所有对象都不再被引用才会实际释放整个slab(8KB)资源。
2、分配大对象:指定buffer对象大于8KB,则会直接申请一块当前所需量大小内存块作为一个slab单元,此slab单元由此对象独享。
4、Buffer的转换
读取文件流避免中文乱码的合理方式
const fs=require('fs');
// highWaterMark用于指定每次读取的字节数,即chunk的大小
const readStream = fs.createReadStream('./a.txt',{highWaterMark:11});
const data=[];
let size=0;
readStream.on('data',function(chunk){
data.push(chunk);
size+=chunk.length;
});
readStream.on('end',function(){
// Buffer.concat(data,size)用于拼接小对象为大对象,指定size时效率会更高(少了计算data实际长度的过程)当size小于实际长度时会截断。
let buffer=Buffer.concat(data,size);
console.log(buffer.toString());
});
在网络传输过程中,传输buffer对象,二进制流方式效率更高。