Buffer(缓冲)

由于 Js 没有读取和操作二进制数据流的机制,所以 nodejs 提供了 Buffer 类来实现这功能,在 TPC 流或文件 I/O 中处理字节流,Buffer 的实例类似于 Js 的数组,但对应于 V8 堆之外的固定大小的原始内存分配。缓冲区的大小是在创建时建立的,不能动态调整大小

由于计算机是二进制来存储的,无论是字符串,数字,文件,音频,视频等等,例如存储一个字符 A,可以通过 charCodeAt 先转为数字(76 => 01001100),然后通过字符集就可以确定对应的数字代表的意义,常见的字符集有 Unicode 和 ASCII 等,字符集定义了什么样数字代表一个字符,字符编码则定义了在二进制文件中要用多少个 bit 来代表这个数字,其他的文件,视频都有相应的规则来定义如何存储响应的二进制数据

Buffer 用法

Stream(流)

nodejs 的流是用来进行二进制数据的传输,流的实现也是使用 buffer 来缓冲数据,stream 继承了 EventEmitter 接口,可以监听数据的流动状态,达到数据流动的目的,流定义了四种类型

  • Readable - 只读的流,例如 fs.createReadStream()
  • Writable - 只写的流,例如 fs.createWriteStream()
  • Duplex - 可读可写流,例如 net.Socket
  • Transform - 可读可写可修改可转换,例如 zlib.createDeflate()

Stream 用法

比如我们使用 fs.createReadStream 来读取一个文件,会把文件数据分块处理,看下面例子,默认创建的流每一块的 buffer 的阈值 highWaterMark 是 16kb,但是用 createReadStream 方法创建的是默认是 64kb

const fs = require("fs");
fs.stat("./img.jpg", (err, res) => {
console.log(res.size / 1024 / 1024); // 6.79m的数据
});
// 使用
const rs = fs.createReadStream("./img.jpg");
const ws = fs.createWriteStream("./copy.jpg");
let i = 0;
rs.on("data", (d) => {
let size = d.length / 1024; // 每次64k,最后一次不满64k
console.log(++i); // 触发109次
ws.write(d);
});
const ws2 = fs.createWriteStream("./copy2.jpg");
rs.pipe(ws2);

延伸阅读

认识 node 核心模块--从 Buffer、Stream 到 fs

深入理解 Node.js Stream 内部机制