Gli Streams consentono di elaborare collezioni di dati a blocchi, ottimizzando l'uso della memoria con file di grandi dimensioni.
Panoramica dei Tipi di Stream
| Tipo | Direzione | Descrizione |
|---|---|---|
Readable |
Sola lettura | Sorgente da cui e possibile leggere dati |
Writable |
Sola scrittura | Destinazione in cui e possibile scrivere dati |
Transform |
Lettura e scrittura | Trasforma o modifica i dati mentre transitano |
Duplex |
Lettura e scrittura | Sia leggibile che scrivibile con canali indipendenti (es. socket TCP) |
Pipeline e il moderno stream/promises
Node.js moderno mette a disposizione pipeline per concatenare gli stream con pulizia automatica delle risorse e gestione degli errori:
const { pipeline } = require('stream/promises');
const fs = require('fs');
const zlib = require('zlib');
async function compressFile() {
await pipeline(
fs.createReadStream('source.tar'),
zlib.createGzip(),
fs.createWriteStream('source.tar.gz')
);
console.log('Compressione completata');
}
Creazione di Streams Personalizzati
1. Stream Readable Personalizzato
const { Readable } = require('stream');
function createTimestampStream() {
let count = 0;
return new Readable({
objectMode: true,
read() {
if (count >= 5) {
this.push(null); // Fine del flusso
} else {
this.push({ id: ++count, time: new Date() });
}
}
});
}
2. Stream Transform Personalizzato
const { Transform } = require('stream');
const uppercaseTransformer = new Transform({
transform(chunk, encoding, callback) {
const transformed = chunk.toString().toUpperCase();
callback(null, transformed);
}
});
3. Stream Writable Personalizzato
const { Writable } = require('stream');
const consoleWriter = new Writable({
objectMode: true,
write(chunk, encoding, callback) {
console.log('Scrittura blocco:', chunk);
callback();
}
});
Modalità Flowing vs Paused
Gli stream in lettura operano in modalita di pausa (paused) oppure fluida (flowing):
const stream = fs.createReadStream('data.csv');
// L'aggiunta di un listener 'data' attiva automaticamente la modalita flowing
stream.on('data', (chunk) => {
console.log(`Ricevuti ${chunk.length} byte`);
});
// Controllo esplicito del flusso
stream.pause(); // Sospendi temporaneamente gli eventi
stream.resume(); // Riprendi gli eventi di streaming
Eventi degli Stream
| Evento | Applicabile a | Condizione di Attivazione |
|---|---|---|
data |
Readable |
Emesso quando e disponibile un nuovo blocco di dati |
end |
Readable |
Emesso quando non ci sono altri dati da leggere |
finish |
Writable |
Emesso quando tutti i dati scritti sono stati scaricati |
error |
All | Emesso quando si verifica un errore non gestito |
close |
All | Emesso quando il descrittore sottostante viene chiuso |