nodejs 中的 buffer

buffer 是一个元素为16进制的两位数的类数组对象

Buffer是一个典型的JavaScript与C++结合的模块,它将性能相关部分用C++实现,将非性能

相关的部分用JavaScript实现
在这里插入图片描述

Buffer内存分配

Buffer对象的内存分配不是在V8的堆内存中,而是在Node的C++层面实现内存的申请的
Node在内存的使用上应用的是在C++层面申请内存、在JavaScript中分配内存的策略
Node以8 KB为界限来区分Buffer是大对象还是小对象

Buffer 所采用的内存分配机制是slab

slab是一种动态内存管理机制 通过预先申请事后分配的方式运转

slab就是一块申请好固定大小的内存区域,它有三个状态 full完全分配partial部分分配 empty没有被分配

buffer 的转换

Buffer对象可以与字符串之间相互转换。目前支持的字符串编码类型有如下这几种。

  • ASCII
  • UTF-8
  • UTF-16LE/UCS-2
  • Base64
  • Binary
  • Hex

字符串转Buffer对象主要是通过构造函数完成的new Buffer(str, [encoding])
Buffer提供了一个isEncoding()函数来判断编码是否支持转换

Buffer.isEncoding(encoding) 

对于不支持的编码类型,可以借助Node生态圈中的模块完成转换。iconv和iconv-lite两个
模块可以支持更多的编码类型转换
iconv-lite采用纯JavaScript实现,iconv则通过C++调用libiconv库完成。前者比后者更轻量,
无须编译和处理环境依赖直接使用。在性能方面,由于转码都是耗用CPU,在V8的高性能下,少
了C++到JavaScript的层次转换,纯JavaScript的性能比C++实现得更好

iconv-lite无法转换的内容如果是多字节,会输出? ;如果是单字节,则输出?。iconv则有三级降级策略,会尝试翻译无法转换的内容,或者忽略这些内容。如果不设置忽略,iconv对于无法转换的内容将会得到EILSEQ异常
了可读流还有一个设置编码的方法setEncoding()
readable.setEncoding(encoding)
该方法的作用是让data事件中传递的不再是一个Buffer对象,而是编码后的字符串
正确的拼接方式是用一个数组来存储接收到的所有Buffer片段并记录下所有片段的总长度, 然后调用Buffer.concat()方法生成一个合并的Buffer对象。

var chunks = [];
var size = 0;
res.on('data', function (chunk) {
 chunks.push(chunk);
 size += chunk.length;
});
res.on('end', function () { 
 var buf = Buffer.concat(chunks, size);
 var str = iconv.decode(buf, 'utf8');
 console.log(str);
}); 

Buffer 与性能

通过预先转换静态内容为Buffer对象,可以有效地减少CPU的重复使用,节省服务器资源。 在Node构建的Web应用中,可以选择将页面中的动态内容和静态内容分离,静态内容部分可以通 过预先转换为Buffer的方式,使性能得到提升。由于文件自身是二进制数据,所以在不需要改变 内容的场景下,尽量只读取Buffer,然后直接传输,不做额外的转换,避免损耗

发布了77 篇原创文章 · 获赞 7 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_37653449/article/details/89817126