Stream-urile procesează datele incremental, în bucăți, mai degrabă decât să încarce totul în memorie dintr-o dată. Acest lucru le face esențiale pentru date mari (fișiere mari, transferuri de rețea) unde bufferizarea tuturor ar epuiza memoria.
Problema pe care o rezolvă stream-urile
// ❌ loads the ENTIRE file into memory — crashes on a 10GB file
const data = await fs.promises.readFile("huge.csv");
process(data);
// ✅ stream it — constant memory, processes chunk by chunk
fs.createReadStream("huge.csv")
.pipe(transform)
.pipe(fs.createWriteStream("out.csv"));
Cu stream-uri, utilizarea memoriei rămâne constantă indiferent de dimensiunea fișierului — gestionezi o bucată la o dată.
Cele patru tipuri de stream
Readable → source you read FROM (fs.createReadStream, http request)
Writable → destination you write TO (fs.createWriteStream, http response)
Duplex → both readable & writable (TCP socket)
Transform → modify data as it passes through (zlib gzip, encryption)
pipe — conectarea stream-urilor
import { createReadStream, createWriteStream } from "fs";
import { createGzip } from "zlib";
// read → compress → write, all streaming, low memory
createReadStream("file.txt")
.pipe(createGzip()) // Transform: compress on the fly
.pipe(createWriteStream("file.txt.gz"));
pipe conectează un readable la un writable (cu transformări în mijloc), gestionând automat fluxul — modul idiomă de a compune stream-uri.
pipeline — pipe cu gestionarea adecvată a erorilor
import { pipeline } from "stream/promises";
await pipeline(
createReadStream("in.txt"),
createGzip(),
createWriteStream("out.gz")
); // ✅ cleans up all streams on error/completion (pipe alone leaks on errors)
pipeline este preferat în locul .pipe() înlănțuit, deoarece propagă erorile și curață fiecare stream corespunzător.
Unde apar stream-urile
✓ HTTP request/response bodies (req and res ARE streams)
✓ File reading/writing, file uploads/downloads
✓ Compression (zlib), encryption (crypto)
✓ Database cursors, large query results
✓ Real-time data processing, video streaming
Când SĂ NU te obosești
Small data that fits comfortably in memory → readFile/simple buffering is simpler.
Streams add complexity; use them for LARGE or continuous data.
De ce conteaza
Stream-urile sunt o caracteristică definitorie a Node.js pentru manipularea eficientă din punct de vedere al memoriei a datelor mari sau continue — diferența dintre o aplicație care se prăbușește la o încărcare mare și una care gestionează orice dimensiune cu memorie constantă.
Înțelegerea celor patru tipuri, compoziția pipe/pipeline (și de ce pipeline este mai sigur) și faptul că cererile/răspunsurile HTTP sunt ele însele stream-uri este esențial pentru construirea serviciilor scalabile de manipulare a fișierelor, procesare a datelor și proxy-ing în Node.
