NodeJS 中Stream 的基本使用

2020-06-17 06:43:05易采站长站整理

console.log(str);
});
// 0123

在上面代码中如果读取的文件内容是中文,每次读取的 highWaterMark 为两个字节,不能组成一个完整的汉字,在每次读取时进行 += 操作会默认调用 toString 方法,这样会导致最后读取的结果是乱码。

在以后通过流操作文件时,大部分情况下都是在操作 Buffer,所以应该用下面这种方式来获取最后读取到的结果。


let fs = require("fs");
let rs = fs.createReadStream("1.txt", {
start: 0,
end: 3,
highWaterMark: 2
});
// 存储每次读取回来的 Buffer
let bufArr = [];
rs.on("data", data => {
bufArr.push(data);
});
rs.on("end", () => {
console.log(Buffer.concat(bufArr).toString());
});
// 0123

3、暂停状态

在流动状态中,一旦开始读取文件,会不断的触发 data 事件,直到读完,暂停状态是我们每读取一次就直接暂停,不再继续读取,即不再触发 data 事件,除非我们主动控制继续读取,就像水龙头打开放水一次后马上关上水龙头,下次使用时再打开。

类似于开关水龙头的动作,也就是暂停和恢复读取的动作,在可读流返回的 rs 对象上有两个对应的方法, pause 和 resume 。

在下面的场景中我们把创建可读流的结尾位置更改成 9 ,在每次读两个字节并暂停一秒后恢复读取,直到读完 0~9 十个数字。


let fs = require("fs");
let rs = fs.createReadStream("1.txt", {
start: 0,
end: 9,
hithWaterMark: 2
});
let bufArr = [];
rs.on("data", data => {
bufArr.push(data);
rs.pause(); // 暂停读取
console.log("暂停", new Date());
setTimeout(() => {
rs.resume(); // 恢复读取
}, 1000)
});
rs.on("end", () => {
console.log(Buffer.concat(bufArr).toString());
});
// 暂停 2018-07-03T23:52:52.436Z
// 暂停 2018-07-03T23:52:53.439Z
// 暂停 2018-07-03T23:52:54.440Z
// 暂停 2018-07-03T23:52:55.442Z
// 暂停 2018-07-03T23:52:56.443Z
// 0123456789

4、错误监听

在通过可读流读取文件时都是异步读取,在异步读取中如果遇到错误也可以通过异步监听到,可读流返回值 rs 对象可以通过 error 事件来监听错误,在读取文件出错时触发回调函数,回调函数参数为 err ,即错误对象。


let fs = require("fs");
// 读取一个不存在的文件
let rs = fs.createReadStream("xxx.js", {
highWarterMark: 2
});
let bufArr = [];
rs.on("data", data => {
bufArr.push(data);
});
rs.on("err", err => {
console.log(err);
});
rs.on("end", () => {
console.log(Buffer.concat(bufArr).toString());