In Node.js verwende ich die Methode fs.createWriteStream
, um Daten an eine lokale Datei anzufügen. In der Node-Dokumentation erwähnen sie das drain
-Ereignis bei Verwendung von fs.createWriteStream
, aber ich verstehe es nicht.
Wie kann ich im obigen Code das Drain-Ereignis verwenden? Wird das Ereignis unten ordnungsgemäß verwendet?
%Vor% Das Ereignis drain
wird verwendet, wenn der interne Puffer eines schreibbaren Streams geleert wurde.
Dies kann nur passieren, wenn die Größe des internen Puffers einmal die highWaterMark
-Eigenschaft überschritten hat. Dies sind die maximalen Datenbytes, die im internen Puffer eines schreibbaren Streams gespeichert werden können, bis das Lesen aus der Datenquelle beendet wird.
Die Ursache für so etwas kann auf Setups zurückzuführen sein, bei denen eine Datenquelle schneller aus einem Stream gelesen wird als auf eine andere Ressource geschrieben werden kann. Nimm zum Beispiel zwei Streams:
%Vor% Stellen Sie sich nun vor, dass die Datei read
auf einer SSD liegt und mit 500MB / s lesen kann und write
auf einer Festplatte ist, die nur in 150MB/s
schreiben kann. Der Schreibstrom kann nicht mithalten und beginnt, Daten im internen Puffer zu speichern. Sobald der Puffer das highWaterMark
erreicht hat, was standardmäßig 16 KB ist, werden die Schreibvorgänge false
zurückgeben, und der Strom wird intern einen Abfluss in die Warteschlange stellen. Sobald die Länge des internen Puffers 0 ist, wird das Ereignis drain
ausgelöst.
So funktioniert ein Abfluss:
%Vor% Und das sind die Voraussetzungen für einen Abfluss, der Teil der Funktion writeOrBuffer
ist:
Um zu sehen, wie das drain
-Ereignis verwendet wird, nehmen Sie das Beispiel aus der Node.js-Dokumentation.
Das Ziel der Funktion besteht darin, 1.000.000 Mal in einen beschreibbaren Stream zu schreiben. Was passiert, ist eine Variable ok
wird auf true gesetzt, und eine Schleife wird nur ausgeführt, wenn ok
wahr ist. Für jede Schleifeniteration wird der Wert von ok
auf den Wert von stream.write()
gesetzt, der den Wert false zurückgibt, wenn ein drain
erforderlich ist. Wenn ok
falsch wird, wartet der Ereignishandler für drain
und setzt den Schreibvorgang fort.
In Bezug auf Ihren Code müssen Sie das drain
-Ereignis nicht verwenden, da Sie nur einmal direkt nach dem Öffnen Ihres Streams schreiben. Da Sie noch nichts in den Stream geschrieben haben, ist der interne Puffer leer, und Sie müssten mindestens 16 KB in Blöcken schreiben, damit das Ereignis drain
ausgelöst wird. Das drain
-Ereignis dient zum Schreiben vieler Male mit mehr Daten als die highWaterMark
-Einstellung Ihres schreibbaren Streams.
Stellen Sie sich vor, Sie verbinden zwei Streams mit sehr unterschiedlichen Bandbreiten, zum Beispiel das Hochladen einer lokalen Datei auf einen langsamen Server. Der (schnelle) Dateistrom sendet Daten schneller als der (langsame) Socket-Stream ihn verbrauchen kann.
In dieser Situation speichert node.js die Daten im Speicher, bis der langsame Stream die Möglichkeit hat, sie zu verarbeiten. Dies kann problematisch werden, wenn die Datei sehr groß ist.
Um dies zu vermeiden, gibt Stream.write
false
zurück, wenn der zugrunde liegende Systempuffer voll ist. Wenn Sie mit dem Schreiben aufhören, gibt der Stream später ein drain
-Ereignis aus, um anzuzeigen, dass der Systempuffer geleert hat und es angemessen ist, erneut zu schreiben.
Sie können pause/resume
den lesbaren Stream verwenden und die Bandbreite des lesbaren Streams steuern.
Besser: Sie können readable.pipe(writable)
verwenden, was das für Sie tut.
BEARBEITEN : Es gibt einen Fehler in Ihrem Code: unabhängig davon, was write
zurückgibt, wurden Ihre Daten geschrieben. Sie müssen es nicht erneut versuchen. In Ihrem Fall schreiben Sie data
zweimal.
So etwas würde funktionieren:
%Vor%Tags und Links javascript node.js stream