nodejs的文件流 stream

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;

    // 可以根据预估量超出之后,重新写入,这样就不会浪费内存空间

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值