本文主要是介绍【Node】Buffer 与 Stream,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
node 为什么会出现 Buffer 这个模块
在最初的时候,JavaScript 只运行在浏览器端,
对于处理 Unicode 编码的字符串很容易,但是对于处理二进制以及非 Unicode 编码的数据便无能为力。
不过对于 Server 端操作来说 网络I/O 以及 文件I/O 的处理是必须的,所以 Node 中便提供了 Buffer 类处理二进制的数据。
二进制缓冲区 Buffer
一个 Buffer 类似于一个整数数组,可以取下标,有length属性,有剪切复制操作等,很多API也类似数组,但Buffer的大小在被创建时确定,且无法调整。
Buffer 可以与 String 互相转化,还可以设置字符集编码。
Buffer 用来处理文件 I/O、网络 I/O传输的二进制数据,String 用来呈现。
在处理文件 I/O、网络 I/O传输的二进制数据时,应该尽量以 Buffer 形式直接传输,速度会得到很好的提升。
Buffer 是一个典型的 JavaScript 与 C++ 结合的模块,与性能有关的用 C++ 来实现,JavaScript 负责衔接和提供接口。
Buffer 所占的内存不是 V8 堆内存,是独立于 V8 堆内存之外的内存,通过 C++ 层面实现内存申请。
可以说真正的内存是 C++层面提供的,而JavaScript分配内存 可以说是 JavaScript层面只是使用它。
小结:Buffer 所占用的内存不是通过 V8 分配的,属于 堆外内存。
为了高效使用申请来的内存,Node 采用了 slab分配机制。slab 具有如下3种形态:
- full:完全分配状态
- partial:部分分配状态
- empty:未被分配状态
Node 以 8KB 为界限来区分 Buffer 是大对象还是小对象:
Buffer.poolSize = 8 * 1024;
Buffer 对象是在 JavaScript层面的,能被 V8 的垃圾回收标记回收。
但是其内部的 parent 指向的 SlowBuffer 对象却来自于 Node 自身的 C++ 中的定义,是 C++层面上的Buffer 对象,所用内存不在 V8 的堆中。
小结:
真正的内存是在 Node 的 C++ 层面提供的,JavaScript 层面只是使用它。
当进行小而频繁的 Buffer 操作时,采用 slab 的机制进行预先申请和事后分配,使得 JavaScript 到操作系统之间不必有过多的内存申请方面的系统调用。
对于大块的 Buffer 而言,则直接使用 C++ 层面提供的内存,无需细腻的分配操作。
由于 Buffer太过常见,Node 进程在启动时就已经加载了它,并将其放在全局对象(global)上。所以在使用 Buffer时,无需通过 require() 即可直接使用。
Buffer 字符编码
通过使用字符编码,可以实现 Buffer实例与 JavaScript字符串之间的相互转换。
- ascii —— 仅适用于7位ASCII数据。此编码速度很快,如果设置则会剥离高位。
- utf8 —— 多字节编码的 Unicode字符。许多网页和其他文档格式都是用UTF-8。
- base64 —— Base64编码。当从字符串创建Buffer时,此编码也会正确地接受RFC 4648第5节中指定的“URL和文件名安全字母”。
- binary —— 一种将 Buffer编码成单字节编码字符串的方法。
- hex —— 将每个字节编码成两个十六进制的字符。
字符串 与 Buffer类型互传
字符串转 Buffer:Buffer.from()
const buf = Buffer.from('Node.js 技术栈', 'UTF-8');console.log(buf); // <Buffer 4e 6f 64 65 2e 6a 73 20 e6 8a 80 e6 9c af e6 a0 88>
console.log(buf.length); // 17
Buffer 转字符串:toString([encoding], [start], [end])
const buf = Buffer.from('Node.js 技术栈', 'UTF-8');console.log(buf); // <Buffer 4e 6f 64 65 2e 6a 73 20 e6 8a 80 e6 9c af e6 a0 88>
console.log(buf.length); // 17
console.log(buf.toString('UTF-8', 0, 9)); // 'Node.js �'
运行查看,可以看到以上输出结果为 Node.js �, 出现了乱码。
转换过程中为什么出现乱码?
问题出在这里一个中文在UTF-8下占用3个字节,“技”这个字在 buf 中对应的字节为 8a80e6,而我们设定的范围为0~9,
因此只输出了8a,这个时候就会造成字符被截断,出现乱码的情况。要想完整出现“技”这个字,则应该截取到11位。
console.log(buf.toString('UTF-8', 0, 11)); // 'Node.js 技'
Buffer 的拼接
Buffer 在使用场景中,通常是以一段一段的方式传输。
var fs = require('fs');var rs = fs.createReadStream('test.txt');
var dat
这篇关于【Node】Buffer 与 Stream的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!