Buffer(缓冲)
由于Js没有读取和操作二进制数据流的机制,所以nodejs提供了Buffer类来实现这功能,在TPC流或文件I/O中处理字节流,Buffer的实例类似于Js的数组,但对应于V8堆之外的固定大小的原始内存分配。缓冲区的大小是在创建时建立的,不能动态调整大小
由于计算机是二进制来存储的,无论是字符串,数字,文件,音频,视频等等,例如存储一个字符A,可以通过charCodeAt先转为数字(76 => 01001100),然后通过字符集就可以确定对应的数字代表的意义,常见的字符集有Unicode和ASCII等,字符集定义了什么样数字代表一个字符,字符编码则定义了在二进制文件中要用多少个bit来代表这个数字,其他的文件,视频都有相应的规则来定义如何存储响应的二进制数据
Stream(流)
nodejs的流是用来进行二进制数据的传输,流的实现也是使用buffer来缓冲数据,stream继承了 EventEmitter 接口,可以监听数据的流动状态,达到数据流动的目的,流定义了四种类型
- Readable - 只读的流,例如
fs.createReadStream()
- Writable - 只写的流,例如
fs.createWriteStream()
- Duplex - 可读可写流,例如
net.Socket
- Transform - 可读可写可修改可转换,例如
zlib.createDeflate()
比如我们使用 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);