Node中Buffer的深度解析
Node中Buffer的深度解析
在Node中,应用需要处理网络协议、操作数据库、处理图片、接收上传文件等,在网络流和文件的操作中,还要处理大量二进制数据,JavaScript自有的字符串远远不能满足这些需求,于是Buffer对象应运而生。
Buffer是一个像Array的对象,但它主要用于操作字节
系统级的Buffer
在操作系统中,也有一个Buffer,翻译为缓冲区,它的作用如下。
-
用于临时存放IO设备上的数据,现代计算机遵循冯洛伊曼架构,CPU不能直接操作硬盘,需要通过内存间接操作,Buffer是用于缓存硬盘读写的数据。
-
减少写入次数,下载大文件时,会先将文件下载到缓冲区,最后一次写入硬盘。
-
应用程序无需等待真正写入到硬盘即可继续执行。
Node中的Buffer
简介
-
Buffer是典型的内建模块+核心模块结合的模块。
-
Node启动时就加载了Buffer模块,可以无需
require
即可使用 -
Buffer的元素为16进制的2位数,即0-255
作用
-
处理大量二进制数据
-
解决由于V8内存限制导致的无法读取超过2G的大文件。
-
对比String有更优的性能
-
字符串与Buffer之间有实质上的差异,即Buffer是二进制数据,字符串与Buffer之间存在
编码关系
。
内存分配
Node采用了slab分配机制
为Buffe分配内存
-
Node安装
slab单元
分配内存,每个slab单元为8kb。 -
当首次分配一个小于8kb的Buffer时,从新的slab分配
-
当再次分配时,优先检查
已使用slab
中是否有剩余空间,然后分配。 -
只有当slab中所有Buffer都释放时,此slab才可以被回收。
-
当Buffer大于8kb时,直接使用C++层提供的
SlowBuffer
分配。 -
的内存是在Node的C++层面提供的
Buffer转换
-
字符串转Buffer:
new Buffer(str, [encoding]);
-
Buffer转字符串:
buf.toString([encoding], [start], [end])
-
判断Node中支持的编码类型:
Buffer.isEncoding(encoding);
-
Buffer拼接:推荐使用第二种, 第一种的问题在于setEncoding支持的编码不多。
// 1、使用setEncoding var rs = fs.createReadStream('test.md', { highWaterMark: 11}); rs.setEncoding('utf8'); var data = ""; rs.on("data", function (chunk){ data += chunk; }); rs.on("end", function () { console.log(data); }); // 2、使用Buffer.concat 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代替字符串,可以提升传输效率和速率,增大网络吞吐量。
-
对静态文件预先转换问Buffer,然后进行网络传输。(不要动态转换,因为转换过程需要消耗CPU资源)
-
fs.createReadStream()方法可以将文件已Buffer格式分段读取。highWaterMark属性设置大大影响此方法的性能。
转载自:https://www.wddsss.com/main/displayArticle/306
标签:node,Node,buffer,data,chunk,js,Buffer,var,slab From: https://www.cnblogs.com/SadicZhou/p/16949984.html