先介绍一下fs.createReadStream
fs.createReadStream(path,options)
//第一个参数
path //文件绝对路径
//第二个参数
options //是一个对象
{
flags: "r", //r代表读取
// encoding:null,
mode: 0o666, //可读可写
autoClose: true, //fs.close 读取完毕后关闭
start: 0, //从第几位读取 包前又包后
end: 9, //读取到第几位
highWaterMark: 3 //每次读取的个数
}
实现一个可读流
const Emitter = require("events");
var fs = require("fs");
class ReadStream extends Emitter {
constructor(p, ops = {}) {
super();
this.path = p;
this.flags = ops.flags || 'r';
this.mode = ops.mode || 0o666;
this.autoClose = ops.autoClose || true;
this.start = ops.start || 0;
this.end = ops.end;
this.highWaterMark = ops.highWaterMark || 64 * 1024;
//纪录偏移量
this.pos = this.start;
//看是否监听了data事件 监听data为流动模式 否则为非流动模式
this.flowing = false;
this.on("newListener", (type) => {
if (type === 'data') {
this.flowing = true;
this.read()
}
})
this.openFile(); //打开文件 fs.open
}
openFile() {
fs.open(this.path, this.flags, this.mode, (err, fd) => {
if (err) {
return this.emit("error", err)
}
this.fd = fd; //保存在实例上 用于后面的读取操作
this.emit('open', fd);
})
}
read() {
if (typeof this.fd !== 'number') {
return this.once('open', () => { this.read() })
}
let buffer = Buffer.alloc(this.highWaterMark);
// console.log(this.fd + '------')
let howMuchToRead = this.end ? Math.min(this.end - this.pos + 1, this.highWaterMark) : this.highWaterMark;
fs.read(this.fd, buffer, 0, howMuchToRead, this.pos, (err, bytesRead) => {
if (bytesRead) {
this.pos += bytesRead;
this.emit('data', buffer.slice(0, bytesRead));
if (this.flowing) {
this.read();
}
} else {//读取完毕
this.emit('end');
if (this.autoClose) {
this.emit('close');
}
}
if(err){
this.emit('error',err);
}
})
}
pause(){
this.flowing = false;
}
resume(){
this.flowing = true;
this.read();
}
}
module.exports = ReadStream
业务层代码
var ReadStream = require("./readStream");
var path = require("path");
var rs = new ReadStream(path.resolve(__dirname, 'name.txt'), {
flags: "r", //r代表读取
// encoding:null,//默认buffer
mode: 0o666, //可读可写
autoClose: true, //fs.close 读取完毕后关闭
start: 0, //从第几位读取 包前又包后
end: 9, //读取到第几位
highWaterMark: 3 //每次读取的个数
})
let bufferArr = [];
rs.on("open", (fd) => {
console.log(fd);
})
rs.on("data", (data) => {
bufferArr.push(data)
rs.pause()
setTimeout(() => {
rs.resume();
console.log("触发");
}, 1000)
});
rs.on('end', () => {
console.log(Buffer.concat(bufferArr).toString());
})
rs.on('close', () => {
console.log('close');
})
rs.on("error", (err) => {
console.log(err)
})
响应结果