乐趣区

关于node.js:文件可读流可写流drain事件背压机制

可读流案例

// 文件可读流创立和生产
const fs = require("fs");
let rs = fs.createReadStream("test.txt", {
  flags: "r",
  encoding: null,
  fd: null,
  mode: 438,
  autoClose: true,
  start: 0,
  //   end:3,
  highWaterMark: 4,
});

// rs.on('data',(chunk)=>{//     console.log(chunk.toString())
//     rs.pause() // 暂停
//     setTimeout(() => {//         rs.resume() // 切回流动状态
//     }, 1000); // 1 秒后持续,直到完结
// })

// rs.on("readable", () => {//   //   let data = rs.read();
//   //   console.log(data);
//   let data;
//   //   while ((data = rs.read()) !== null) {//   //     console.log(data.toString());
//   //   }
//   while ((data = rs.read(2)) !== null) { // 每次读两字节,缓冲区读完之后取 highWaterMark 字节长度到缓冲区
//     console.log(data.toString());
//     console.log(rs._readableState.length);
//   }
// });

rs.on("open", (fd) => {console.log(fd, "file open");
});

rs.on("close", (fd) => {console.log("默认不会被执行,数据被读取完(生产)后才会被执行");
});

rs.on("data", (chunk) => {console.log(chunk);
});

rs.on("end", () => {console.log('数据被清空过之后会被执行');
});

rs.on("err", (err) => {console.log('出错时会被执行');
});

可写流
案例

const ws = fs.createWriteStream("test.txt", {
  flags: "w",
  mode: 438,
  fd: null,
  encoding: "utf-8",
  start: 0,
  highWaterMark: 3,
});

// ws.write("写入内容", () => {//   console.log("write over1");
// });
// ws.write("能够屡次写入,前面的默认会被追加", () => {//   console.log("write over2");
// });

// ws.write(1, () => { // 会报错,这里默认接管字符串或者 buffer => fs rs
//   console.log("write over1");
// });

ws.on("open", (fd) => {console.log("open", fd);
});

ws.on("close", () => {
  // 数据写入操作全副实现后再执行,end 之后
  console.log("file close");
});

// end 执行之后就意味着数据写入操作实现
ws.end(); // end 中也能够放入要写的内容,最初最终执行写入

ws.on("err", (err) => {console.log("err");
});

可写流写入速度问题

let ws = fs.createWriteStream("test.txt", {highWaterMark: 3,});

let flag = ws.write("1");
console.log(flag); // true

flag = ws.write("2");
console.log(flag);// true

flag = ws.write("3");
console.log(flag); // false ,
// 1,第一次调用 write 办法时是将数据间接写入到文件中
// 2,第二次开始 write 办法就是将数据写入至缓存区
// 3,生产速度和生产数据不一样,个别状况下生产速度要比生产速度快很多
// 4,当 flag 为 false 之后,false 不代表以后数据不能被执行写入,然而咱们应该告知数据生产者,以后生产速度曾经跟不上生产速度,这时候咱们会将
// 可读流的模块批改为暂停模式
// 5,当数据生产者暂停之后,消费者会缓缓消化它外部缓存中的数据,直到咱们可再次被执行写入操作
// 6,当缓冲区能够持续写入数据时通过 drain 工夫让生产者直到
ws.on("drain", () => {console.log("drain work");
});

管制写入速度,被压机制

分批限流

let ws = fs.createWriteStream("test.txt", {highWaterMark: 3,});
// ws.write('前端性能')
let source = "前端性能".split("");
let num = 0;
let flag = true;
function excuteWrite() {
  flag = true;
  while (num !== 4 && flag) {flag = ws.write(source[num]);
    num++;
  }
}
excuteWrite();
ws.on("drain", () => {console.log("drain work");
  excuteWrite();});

或者这里间接应用rs.pipe(ws)

退出移动版