1.文件可读流
const fs= require("fs");
const stm =fs.createReadStream("./file.txt",{
flags: "r", // 读取模式
autoClose: true, // 读取完毕自动关闭流
emitClose: true,
start: 3, // 开始位置
end: 11, // 结束位置
highWaterMark: 6 // 一次文件读取的最大量【内存开辟大小】
});
let bufArr=[];
// 文件打开事件
stm.on("open", function(){
console.log("打开文件")
})
// 获取数据事件
stm.on("data",function(dt){
bufArr.push(dt);
})
// 读取数据结束事件
stm.on("end",function(){
console.log(Buffer.concat(bufArr).toString());
})
// 文件关闭事件
stm.on("close",function(){
console.log("关闭文件")
})
stm.on("error",function(err){
console.log(err);
})
2.文件读取流的原理
const EventEmitter = require("events");
const fs = require("fs");
class MyReadStream extends EventEmitter {
constructor(path, options) {
super();
this.path = path;
this.flags = options.flags || "r";
this.autoClose = options.autoClose || true;
this.start = options.start || 0;
this.mode = options.mode || 0o666; // 可读可写不可执行模式
this.end = options.end;
this.highWaterMark = options.highWaterMark || 64 * 1024; // 一次读取的内存量
this.pos = this.start;
this.open();
this.on("newListener", (type) => {
if (type === "data") {
this.read();
}
});
}
open() {
fs.open(this.path, this.flags, (err, fd) => {
if (err) {
return this.emit("error", err);
}
this.fd = fd;
this.emit("open", fd);
});
}
read() {
if ((typeof this.fd !== "number")) {
console.log("此时还没有打开文件");
return this.once("open", this.read); // 因为data和open事件用的时候是同步的, 监听open事件,打开后在读取文件
}
let buf = Buffer.alloc(this.highWaterMark);
let howMuchToRead = this.end
? Math.min(this.end - this.pos + 1, this.highWaterMark)
: this.highWaterMark;
fs.read(this.fd, buf, 0, howMuchToRead, this.pos, (err, readSize) => {
if (err) {
return this.emit("error", err);
}
if (readSize) {
this.pos += readSize;
this.emit("data", buf);
this.read();
} else {
this.emit("end");
this.close();
}
});
}
close() {
fs.close(this.fd, () => {
this.emit("close");
});
}
}
module.exports = MyReadStream;
3.读取文件写入新的文件 (Pipe管道)
const fs= require("fs");
const path= require("path");
const rs= fs.createReadStream(path.resolve(__dirname,"1.pdf")); // 可读流
const ws= fs.createWriteStream(path.resolve(__dirname,"new3.pdf")); // 可写流
rs.on("data",function(data){
console.log(data);
})
rs.pipe(ws); // 写入
4.可写流
/**
* Returns a new `WriteStream` object.
* @param path A path to a file. If a URL is provided, it must use the `file:` protocol.
* URL support is _experimental_.
*/
export function createWriteStream(path: PathLike, options?: string | {
flags?: string;
encoding?: BufferEncoding; //编码
fd?: number; // 文件标识符
mode?: number; // 模式 r w等
autoClose?: boolean; // 是否自动关闭
emitClose?: boolean;
start?: number; // 开始位置 一般不用传 默认0
highWaterMark?: number; // 写入的预估量,超过了预估量,该方法会返回true
}): WriteStream;
// 可以根据预估量超出之后,重新写入,这样就不会浪费内存空间