Node.js Stream
Node.js Stream est une interface abstraite pour la gestion de données en streaming, largement utilisée dans des scénarios tels que les opérations sur fichiers et la communication réseau.
Un avantage majeur du traitement de données en streaming est que les données peuvent être traitées pendant la transmission sans attendre le chargement de l'ensemble des données, ce qui permet à Node.js de gérer efficacement de grandes quantités de données sans consommer une mémoire excessive.

Stream est une interface abstraite, et de nombreux objets dans Node implémentent cette interface. Par exemple, l'objet request pour une requête de serveur HTTP est un Stream, tout comme stdout (sortie standard).
Node.js Stream est une façon de gérer les flux de données. Il vous permet de traiter les données de manière streaming au lieu de charger toutes les données en mémoire d'un coup. C'est très utile pour gérer de grandes quantités de données ou réaliser des transferts de données efficaces.
Dans Node.js, il existe quatre types de flux :
Readable- Opérations de lecture.
Writable- Opérations d'écriture.
Duplex- Opérations de lecture et d'écriture.
Transform- Opérations qui écrivent des données, puis lisent le résultat.
Tous les objets Stream sont des instances d'EventEmitter. Les événements courants incluent :
data- Déclenché lorsque des données sont disponibles en lecture.
end- Déclenché lorsqu'il n'y a plus de données à lire.
error- Déclenché lorsqu'une erreur se produit lors de la réception ou de l'écriture.
finish- Déclenché lorsque toutes les données ont été écrites dans le système sous-jacent.
Ce tutoriel présentera les opérations courantes sur les flux.
Lecture de données à partir d'un flux
Les flux lisibles courants incluent les flux de lecture de fichiers et les flux de réponse aux requêtes réseau.
Créez un fichier input.txt avec le contenu suivant :
Example官网地址:www.example.com
Créez un fichier main.js avec le code suivant :
Exemple
var data = '';
// Créer un flux lisible
var readerStream = fs.createReadStream('input.txt');
// Définir l'encodage sur utf8.
readerStream.setEncoding('UTF8');
// Gérer les événements de flux --> data, end et error
readerStream.on('data', function(chunk) {
data += chunk;
});
readerStream.on('end',function(){
console.log(data);
});
readerStream.on('error', function(err){
console.log(err.stack);
});
console.log("Exécution du programme terminée");
Le résultat d'exécution du code ci-dessus est le suivant :
程序执行完毕 Example官网地址:www.example.com
Flux inscriptible
Un flux inscriptible est utilisé pour écrire des données vers une destination. Les flux inscriptibles courants incluent les flux d'écriture de fichiers et les flux d'envoi de requêtes réseau.
Créez un fichier main.js avec le code suivant :
Exemple
var data = 'Exemple d'adresse de site officiel : www.example.com';
// Créer un flux en écriture, écrivant dans le fichier output.txt
var writerStream = fs.createWriteStream('output.txt');
// Écrire des données en utilisant l'encodage utf8
writerStream.write(data,'UTF8');
// Marquer la fin du fichier
writerStream.end();
// Gérer les événements de flux --> finish, error
writerStream.on('finish', function() {
console.log("Écriture terminée.");
});
writerStream.on('error', function(err){
console.log(err.stack);
});
console.log("Exécution du programme terminée");
Le programme ci-dessus écrit les données de la variable data dans le fichier output.txt. Le résultat de l'exécution du code est le suivant :
$ node main.js 程序执行完毕 写入完成。
Voir le contenu du fichier output.txt :
$ cat output.txt Example官网地址:www.example.com
Flux duplex
Un flux duplex possède à la fois des capacités de lecture et d'écriture.
Un flux duplex typique est une socket TCP.
Exemple
// Créer un serveur TCP
const server = net.createServer((socket) => {
console.log('Client connecté.');
// Lire les données du client
socket.on('data', (data) => {
console.log('Données reçues :', data.toString());
});
// Envoyer des données au client
socket.write('Bonjour, Client !\n');
// Écouter l'événement de fermeture
socket.on('end', () => {
console.log('Client déconnecté.');
});
});
server.listen(3000, () => {
console.log('Serveur à l'écoute sur le port 3000.');
});
Flux de transformation
Un flux de transformation est un type spécial de flux duplex qui peut modifier ou transformer des données. Les flux de transformation courants incluent les flux de compression et de décompression.
Exemple
const fs = require('fs');
// Créer un flux lisible
const readableStream = fs.createReadStream('example.txt');
// Créer un flux de transformation (compression)
const gzip = zlib.createGzip();
// Créer un flux inscriptible
const writableStream = fs.createWriteStream('example.txt.gz');
// Faire passer le flux lisible dans le flux de transformation, puis dans le flux inscriptible
readableStream.pipe(gzip).pipe(writableStream);
// Écouter l'événement d'achèvement
writableStream.on('finish', () => {
console.log('Fichier compressé avec succès.');
});
Flux avec pipe
Un pipe fournit un mécanisme pour connecter un flux de sortie à un flux d'entrée.
Habituellement, on l'utilise pour obtenir des données d'un flux et transmettre les données à un autre flux.
Comme le montre l'image ci-dessus, nous comparons les fichiers à des barils remplis d'eau, et l'eau est le contenu des fichiers. Nous utilisons un tuyau pour relier les deux barils afin que l'eau s'écoule d'un baril à l'autre, ce qui réalise progressivement le processus de copie de fichiers volumineux.
Dans l'exemple suivant, nous lisons le contenu d'un fichier et écrivons le contenu dans un autre fichier.
Définissez le contenu du fichier input.txt comme suit :
Example官网地址:www.example.com 管道流操作实例
Créez un fichier main.js avec le code suivant :
Exemple
// Créer un flux lisible
var readerStream = fs.createReadStream('input.txt');
// Créer un flux inscriptible
var writerStream = fs.createWriteStream('output.txt');
// Opérations de lecture et d'écriture par pipe
// Lire le contenu de input.txt et écrire le contenu dans output.txt
readerStream.pipe(writerStream);
console.log("Exécution du programme terminée");
Le résultat d'exécution du code est le suivant :
$ node main.js 程序执行完毕
Voir le contenu du fichier output.txt :
$ cat output.txt Example官网地址:www.example.com 管道流操作实例
Flux chaîné
Le chaînage est un mécanisme permettant de connecter un flux de sortie à un autre flux et de créer une chaîne de plusieurs opérations de flux.
Les flux chaînés sont généralement utilisés pour les opérations de pipe.
Ensuite, nous utiliserons des pipes et le chaînage pour compresser et décompresser des fichiers.
Créez un fichier compress.js avec le code suivant :
Exemple
var zlib = require('zlib');
// Compresser input.txt dans input.txt.gz
fs.createReadStream('input.txt')
.pipe(zlib.createGzip())
.pipe(fs.createWriteStream('input.txt.gz'));
console.log("Compression du fichier terminée.");
Le résultat d'exécution du code est le suivant :
$ node compress.js 文件压缩完成。
Après avoir effectué les opérations ci-dessus, nous pouvons voir qu'un fichier compressé input.txt.gz a été généré dans le répertoire courant.
Ensuite, décompressons ce fichier. Créez un fichier decompress.js avec le code suivant :
Exemple
var zlib = require('zlib');
// Décompresser input.txt.gz dans input.txt
fs.createReadStream('input.txt.gz')
.pipe(zlib.createGunzip())
.pipe(fs.createWriteStream('input.txt'));
console.log("Décompression du fichier terminée.");
Le résultat d'exécution du code est le suivant :
$ node decompress.js 文件解压完成。
Pause et reprise
Un flux lisible peut mettre en pause et reprendre la lecture des données.
Exemple
const readableStream = fs.createReadStream('example.txt', 'utf8');
readableStream.on('data', (chunk) => {
console.log('Morceau reçu :', chunk);
readableStream.pause(); // Suspendre la lecture
setTimeout(() => {
readableStream.resume(); // Reprendre la lecture
}, 1000);
});
Détruire
Vous pouvez détruire un flux pour libérer des ressources.
Exemple
const readableStream = fs.createReadStream('example.txt', 'utf8');
readableStream.on('data', (chunk) => {
console.log('Morceau reçu :', chunk);
readableStream.destroy(); // Détruire le flux
});