„Wenn ein Arbeiter seine Arbeit gut machen will, muss er zuerst seine Werkzeuge schärfen.“ – Konfuzius, „Die Gespräche des Konfuzius. Lu Linggong“
Titelseite > Programmierung > Streams: Node.js

Streams: Node.js

Veröffentlicht am 01.11.2024
Durchsuche:809

Streams: Node.js

Vollständiger Leitfaden zu Streams in Node.js

Streams in Node.js sind eine leistungsstarke Möglichkeit, Daten kontinuierlich zu lesen und zu schreiben. Sie ermöglichen Ihnen eine effiziente Datenverarbeitung, insbesondere bei großen Informationsmengen oder I/O-Vorgängen. Dieser Leitfaden behandelt die Arten von Streams, ihre Verwendung und praktische Beispiele, die Ihnen helfen, zu verstehen, wie Streams in Node.js funktionieren.

Was sind Streams?

Streams sind Objekte, die es Ihnen ermöglichen, kontinuierlich Daten aus einer Quelle zu lesen oder Daten an ein Ziel zu schreiben. Sie sind ideal, um Daten Stück für Stück zu verarbeiten, anstatt ganze Dateien oder Puffer auf einmal zu lesen oder zu schreiben. Dies ist besonders nützlich, wenn Sie mit großen Datenmengen arbeiten, da es den Speicherverbrauch erheblich reduzieren kann.

Schlüsselkonzepte

  • Flussmodus: Daten fließen automatisch von der Quelle zum Ziel.
  • Pausierter Modus: Daten müssen manuell aus der Quelle gelesen werden.
  • Lesbare Streams: Streams, aus denen Sie Daten lesen können.
  • Beschreibbare Streams: Streams, in die Sie Daten schreiben können.
  • Duplex-Streams: Streams, die Daten sowohl lesen als auch schreiben können.
  • Transformations-Streams: Streams, die die Daten beim Lesen oder Schreiben ändern oder transformieren.

Arten von Streams

  1. Lesbare Streams: Mit diesen Streams können Sie Daten lesen. Beispiele hierfür sind fs.createReadStream() und http.IncomingMessage.

  2. Schreibbare Streams: Mit diesen Streams können Sie Daten schreiben. Beispiele hierfür sind fs.createWriteStream() und http.ServerResponse.

  3. Duplex-Streams: Diese Streams können Daten lesen und schreiben. Beispiele hierfür sind TCP-Sockets und net.Duplex.

  4. Transformations-Streams: Dabei handelt es sich um eine Art Duplex-Stream, der die Daten beim Lesen oder Schreiben ändern kann. Beispiele hierfür sind zlib.createGzip() für die Komprimierung.

Lesbare Streams erstellen

Sie können einen lesbaren Stream erstellen, indem Sie das integrierte fs-Modul zum Lesen von Dateien verwenden oder stream.Readable verwenden, um benutzerdefinierte lesbare Streams zu erstellen.

Beispiel: Lesen einer Datei mit einem lesbaren Stream

const fs = require('fs');

// Create a readable stream
const readableStream = fs.createReadStream('example.txt', { encoding: 'utf8' });

// Handling the 'data' event
readableStream.on('data', (chunk) => {
    console.log('New chunk received:', chunk);
});

// Handling the 'end' event
readableStream.on('end', () => {
    console.log('No more data to read.');
});

Beispiel: Benutzerdefinierter lesbarer Stream

const { Readable } = require('stream');

class MyReadableStream extends Readable {
    constructor(options) {
        super(options);
        this.current = 0;
    }

    _read(size) {
        if (this.current  {
    console.log('Received:', chunk.toString());
});

Beschreibbare Streams erstellen

Sie können beschreibbare Streams mit dem fs-Modul oder durch Erweiterung der stream.Writable-Klasse erstellen.

Beispiel: Schreiben in eine Datei mit einem beschreibbaren Stream

const fs = require('fs');

// Create a writable stream
const writableStream = fs.createWriteStream('output.txt');

// Write data to the stream
writableStream.write('Hello, World!\n');
writableStream.write('Writing to a file using streams.\n');

// End the stream
writableStream.end(() => {
    console.log('Finished writing to file.');
});

Beispiel: Benutzerdefinierter beschreibbarer Stream

const { Writable } = require('stream');

class MyWritableStream extends Writable {
    _write(chunk, encoding, callback) {
        console.log('Writing:', chunk.toString());
        callback(); // Call when done
    }
}

const myWritableStream = new MyWritableStream();
myWritableStream.write('Hello, World!\n');
myWritableStream.write('Writing to custom writable stream.\n');
myWritableStream.end();

Verwenden von Duplex-Streams

Duplex-Streams können Daten gleichzeitig lesen und schreiben. Ein häufiger Anwendungsfall sind TCP-Sockets.

Beispiel: Erstellen eines Duplex-Streams

const { Duplex } = require('stream');

class MyDuplexStream extends Duplex {
    _read(size) {
        this.push('Data from duplex stream\n');
        this.push(null); // No more data
    }

    _write(chunk, encoding, callback) {
        console.log('Received:', chunk.toString());
        callback();
    }
}

const myDuplexStream = new MyDuplexStream();
myDuplexStream.on('data', (chunk) => {
    console.log('Reading:', chunk.toString());
});

// Write to the duplex stream
myDuplexStream.write('Hello, Duplex!\n');
myDuplexStream.end();

Verwenden von Transformationsströmen

Transformationsstreams sind nützlich, um Daten zu ändern, während sie durch den Stream fließen. Sie könnten beispielsweise einen Transformationsstream verwenden, um Daten zu komprimieren.

Beispiel: Erstellen eines Transformationsstreams

const { Transform } = require('stream');

class MyTransformStream extends Transform {
    _transform(chunk, encoding, callback) {
        const upperChunk = chunk.toString().toUpperCase();
        this.push(upperChunk);
        callback();
    }
}

const myTransformStream = new MyTransformStream();
myTransformStream.on('data', (chunk) => {
    console.log('Transformed:', chunk.toString());
});

// Pipe data through the transform stream
process.stdin.pipe(myTransformStream).pipe(process.stdout);

Rohrleitungsströme

Eine der leistungsstarken Funktionen von Streams ist die Möglichkeit, sie zusammenzuführen. Durch Piping können Sie einen lesbaren Stream mit einem beschreibbaren Stream verbinden, was die Datenübertragung erleichtert.

Beispiel: Rohrleitungsströme

const fs = require('fs');

// Create a readable stream
const readableStream = fs.createReadStream('input.txt');

// Create a writable stream
const writableStream = fs.createWriteStream('output.txt');

// Pipe the readable stream to the writable stream
readableStream.pipe(writableStream);

writableStream.on('finish', () => {
    console.log('Data has been written to output.txt');
});

Streamen Sie Ereignisse in Node.js

1. Lesbare Streams-Ereignisse

Lesbare Streams geben mehrere wichtige Ereignisse aus, die Ihnen bei der Verwaltung des Datenflusses helfen:

  • Daten: Wird ausgegeben, wenn ein Datenblock zum Lesen verfügbar ist.
  • end: Wird ausgegeben, wenn keine Daten mehr zum Lesen vorhanden sind.
  • error: Wird ausgegeben, wenn beim Lesen ein Fehler auftritt.
  • close: Wird ausgegeben, wenn der Stream und alle zugrunde liegenden Ressourcen (wie Dateideskriptoren) geschlossen wurden.

Beispiel: Lesbare Stream-Ereignisse

const fs = require('fs');

const readableStream = fs.createReadStream('example.txt');

readableStream.on('data', (chunk) => {
    console.log('Received chunk:', chunk.toString());
});

readableStream.on('end', () => {
    console.log('No more data to read.');
});

readableStream.on('error', (err) => {
    console.error('Error occurred:', err);
});

readableStream.on('close', () => {
    console.log('Stream closed.');
});

2. Beschreibbare Streams-Ereignisse

Beschreibbare Streams geben auch mehrere Ereignisse aus:

  • drain: Wird ausgegeben, wenn der Stream bereit ist, weitere Daten zu akzeptieren, nachdem er voll ist.
  • finish: Wird ausgegeben, wenn alle Daten in den Stream geschrieben wurden und die end()-Methode aufgerufen wurde.
  • error: Wird ausgegeben, wenn beim Schreiben ein Fehler auftritt.
  • close: Wird ausgegeben, wenn der Stream und alle zugrunde liegenden Ressourcen geschlossen wurden.

Beispiel: Beschreibbare Stream-Ereignisse

const fs = require('fs');

const writableStream = fs.createWriteStream('output.txt');

writableStream.on('finish', () => {
    console.log('All data has been written to output.txt');
});

writableStream.on('error', (err) => {
    console.error('Error occurred:', err);
});

// Writing data
writableStream.write('Hello, World!\n');
writableStream.write('Writing to a file using streams.\n');
writableStream.end(); // Call end to finish the writing process

3. Streams-Ereignisse transformieren

Transformations-Streams erben Ereignisse sowohl von lesbaren als auch von beschreibbaren Streams und geben Folgendes aus:

  • Daten: Wird ausgegeben, wenn ein transformierter Block zum Lesen verfügbar ist.
  • end: Wird ausgegeben, wenn keine Daten mehr zur Transformation vorhanden sind.
  • error: Wird ausgegeben, wenn während der Transformation ein Fehler auftritt.
  • finish: Wird ausgegeben, wenn alle Daten verarbeitet und geschrieben wurden.

Beispiel: Stream-Ereignisse transformieren

const { Transform } = require('stream');

class MyTransformStream extends Transform {
    _transform(chunk, encoding, callback) {
        const upperChunk = chunk.toString().toUpperCase();
        this.push(upperChunk);
        callback();
    }
}

const myTransformStream = new MyTransformStream();

myTransformStream.on('data', (chunk) => {
    console.log('Transformed chunk:', chunk.toString());
});

myTransformStream.on('end', () => {
    console.log('No more data to transform.');
});

myTransformStream.on('error', (err) => {
    console.error('Error occurred:', err);
});

// Write data to the transform stream
myTransformStream.write('Hello, World!\n');
myTransformStream.write('Transforming this text.\n');
myTransformStream.end(); // End the stream

Zusammenfassung der Ereignisse

  • Lesbare Streams: Daten, Ende, Fehler, Schließen
  • Beschreibbare Streams: entleeren, beenden, Fehler, schließen
  • Streams transformieren: Erbt Daten, Ende, Fehler und Ende sowohl von lesbaren als auch beschreibbaren Streams

Abschluss

Streams in Node.js bieten eine leistungsstarke und effiziente Möglichkeit, Daten kontinuierlich zu verarbeiten. Sie ermöglichen Ihnen, Daten Stück für Stück zu lesen und zu schreiben, was sie besonders nützlich für E/A-Vorgänge und die Arbeit mit großen Datenmengen macht. Wenn Sie verstehen, wie Sie verschiedene Arten von Streams erstellen und verwenden und wie Sie mit Ereignissen umgehen, können Sie effizientere und skalierbarere Anwendungen in Node.js erstellen.

Ganz gleich, ob Sie lesbare, beschreibbare, Duplex- oder Transformations-Streams erstellen, die Flexibilität der Stream-API ermöglicht es Ihnen, die Datenverarbeitung so zu handhaben, dass sie den Anforderungen Ihrer Anwendung am besten entspricht.

Freigabeerklärung Dieser Artikel ist abgedruckt unter: https://dev.to/harshm03/streams-nodejs-2j32?1 Bei Verstößen wenden Sie sich bitte an [email protected], um ihn zu löschen
Neuestes Tutorial Mehr>

Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.

Copyright© 2022 湘ICP备2022001581号-3