Heim >Web-Frontend >js-Tutorial >Eine kurze Diskussion über die Schreib- und Implementierungsmethoden für beschreibbare Streams in Nodejs

Eine kurze Diskussion über die Schreib- und Implementierungsmethoden für beschreibbare Streams in Nodejs

青灯夜游
青灯夜游nach vorne
2021-06-21 10:08:542168Durchsuche

Dieser Artikel führt Sie durch das beschreibbare Stream-Schreiben in Nodejs und stellt die Implementierung des beschreibbaren Stream-Schreibens von Node vor. Es hat einen gewissen Referenzwert. Freunde in Not können sich darauf beziehen. Ich hoffe, es wird für alle hilfreich sein.

Eine kurze Diskussion über die Schreib- und Implementierungsmethoden für beschreibbare Streams in Nodejs

【Empfohlenes Lernen: „nodejs-Tutorial“】

Beschreibbarer Stream-Writable

fs.createWriteStream-Aufrufbeispiel

  • Die zum ersten Mal gelesenen Daten werden tatsächlich auf das Ziel geschrieben Datei
  • Die für die verbleibenden Zeiten gelesenen Daten hängen davon ab, ob die gelesenen Daten den HighWaterMark überschreiten. Wenn dies der Fall ist, werden sie im Pufferbereich gespeichert und warten darauf, in die Zieldatei geschrieben zu werden Warteschlange zur Generierung verknüpfter Listen für das Caching von Dateilesevorgängen
  • Implementierung verknüpfter Listen und Warteschlangen
https://juejin.cn/post/6973847774752145445

Eine kurze Diskussion über die Schreib- und Implementierungsmethoden für beschreibbare Streams in Nodejs

const fs = require("fs");
const path = require("path");
const bPath = path.join(__dirname, "b.txt");
let ws = fs.createWriteStream(bPath, {
  flags: "w",
  encoding: "utf-8",
  autoClose: true,
  start: 0,
  highWaterMark: 3,
});
ws.on("open", function (fd) {
  console.log("open", fd);
});
ws.on("close", function () {
  console.log("close");
});
 //string 或者buffer,ws.write 还有一个boolea的返回值
ws.write("1");
//flag 表示 当前要写的值是直接是否直接写入文件,不能超出了单次最大写入值highWaterMark
let flag = ws.write("1");
console.log({ flag });//true
flag = ws.write("1");
console.log({ flag });//false
flag = ws.write("1");
console.log({ flag });//false
flag = ws.write("14444444");
console.log({ flag });//false
ws.end(); //write+close,没有调用 end 是不会调用 触发close的,看到这里的小伙伴可以尝试注释end() 看看close的console是否有打印

Standarddatenkonstruktor der Instanz initialisieren ()
const EventEmitter = require("events");
const fs = require("fs");
class WriteStream extends EventEmitter {}
module.exports = WriteStream;

das Die Berechtigungen für .mode-Dateioperationen sind standardmäßig 0o666 (0o bedeutet oktal)

Die von den drei 6ern eingenommenen Positionen entsprechen: den Berechtigungen des Benutzers, zu dem die Datei gehört; den Berechtigungen der Benutzergruppe, zu der die Datei gehört . Seine Berechtigungen stellen die Berechtigungen anderer Benutzer dar. Die Berechtigungen sind: r--readable (entsprechend dem Wert 4), w--writable (entsprechend dem Wert 2), x--executable (entsprechend der Wert 1, beispielsweise befindet sich unter dem Ordner eine Markierung wie .exe, die darauf hinweist, dass der Klick direkt ausgeführt werden kann), sodass die Betriebsberechtigungen der drei Benutzergruppen für die Datei standardmäßig lesbar und beschreibbar sind

open()

Rufen Sie fs.open() auf

    Rufen Sie die Methode zum Öffnen der Emit-Instanz zurück und der Rückgabewert fd von fs.open wird als Parameter übergeben
  • // 用链表 生成队列 对 文件缓存区的读取 进行优化
    const Queue = require("./queue");

      write()
    • Konvertieren Sie die von der Instanz übergebene Datei, die geschrieben werden muss. Das Datenformat ist Puffer.
    • Bestimmen Sie, ob die Länge der geschriebenen Daten größer als highWaterMark ist. Wenn sie den Erwartungen entspricht, sind die aus der Datei gelesenen Daten Wird im Cache gespeichert und nicht direkt in die Zieldatei geschrieben (außer, ob die Datei zum ersten Mal gelesen wird). erster Lesevorgang. Der erste Lesevorgang schreibt direkt und ruft _write auf (zu implementieren).

    • Warteschlangen-Ausführungsreihenfolge, First-In-First-Out-Prinzip
    • this.cache.poll() nimmt nacheinander die Header-Daten und führt this._write aus. Geben Sie die Zieldatei ein

    • Wenn die aus der Cache-Warteschlange abgefragten Daten nicht vorhanden sind, bedeutet dies dass es sich um den ersten Schreibvorgang handelt ||Die Cache-Warteschlange wurde geleert. this.writing = false; Die nächste gelesene Datei kann direkt in die Zieldatei geschrieben werden
  • Wenn this.needDrain erneut die Erwartungen erfüllt, wird die Datei gelesen und die Daten im Cache gespeichert, ohne direkt in die Zieldatei zu schreiben

 constructor(path, options = {}) {
    super();
    this.path = path;
    this.flags = options.flags || "w";
    this.encoding = options.encoding || "utf8";
    this.mode = options.mode || 0o666; //默认8进制 ,6 6 6  三组分别的权限是 可读可写
    this.autoClose = options.start || 0;
    this.highWaterMark = options.highWaterMark || 16 * 1024; //默认一次读取16个字节的数据
    this.len = 0; //用于维持有多少数据还没有被写入文件中
    //是否根据等待当前读取的最大文数据 排空后再写入
    this.needDrain = false; //
    // 缓存队列 用于存放 非第一次的文件读取 到的数据,因为第一次读取 直接塞入目标文件中
    // 除第一次 的文件读取数据的都存放再缓存中
    // this.cache = [];
    // 队列做缓存
    this.cache = new Queue();
    // 标记是否是第一次写入目标文件的标识
    this.writing = false;
    this.start = options.start || 0;
    this.offset = this.start; //偏移量
    this.open();
  }
_write( )

  • fs.open() ist asynchron. Nach erfolgreichem Lesen wird fd vom Typ number sein Typ ist Zahl)
  • fd-Typ Für Zahl: Rufen Sie fs.write auf, schreiben Sie den aktuellen Block,

 open() {
    fs.open(this.path, this.flags, this.mode, (err, fd) => {
      this.fd = fd;
      this.emit("open", fd);
    });
  }
testen Sie die benutzerdefinierten beschreibbaren

     write(chunk, encoding = this.encoding, cb = () => {}) {
        //  将数据全部转换成buffer
        chunk = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
    
        this.len += chunk.length;
        // console.log({chunk},this.len )
        let returnValue = this.len < this.highWaterMark;
        //当数据写入后,需要在手动的将this.len--
        this.needDrain = !returnValue; //如果达到预期 后 的文件读取 到数据存放再缓存里 不直接写入目标文件
        //清空缓存 对用户传入的回调 进行二次包装
        let userCb = cb;
        cb = () => {
          userCb();
          //清空buffer
          this.clearBuffer();//马上实现
        };
    
        //此时需要判断 是否是第一次读取,第一次读取 直接写入调用 _write
        if (!this.writing) {
          // 第一次||缓存队列已清空完毕
          this.writing = true;
          // console.log("first write");
          this._write(chunk, encoding, cb);//马上实现
        } else {
        //缓存队列尾部offer 当前读取到的数据等待写入目标文件
          this.cache.offer({
            chunk,
            encoding,
            cb,
          });
        }
        return returnValue;
      }
  • 10 Zahlen, schreiben Sie sie nacheinander und erreichen Sie dreimal den maximal erwarteten Wert , und löschen Sie sie dann dreimal. Die zwischengespeicherten Ergebnisse entsprechen den Erwartungen. Bitte besuchen Sie:
  • Programmiervideo
  • ! !

Das obige ist der detaillierte Inhalt vonEine kurze Diskussion über die Schreib- und Implementierungsmethoden für beschreibbare Streams in Nodejs. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:juejin.cn. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen
Vorheriger Artikel:So lösen Sie Javascript void0Nächster Artikel:So lösen Sie Javascript void0