Chapter 9 of 12
Streams process data in chunks rather than loading everything into memory at once. They're how Node.js efficiently handles large files, video streams, real-time data, and network responses.
ANALOGY
A water pipe, not a bucket. Copying a 10GB file using a bucket means loading all 10GB into memory, then pouring it out. A pipe moves the water continuously — you never hold it all at once. Streams work the same way. They're how Node.js processes a 10GB log file without running out of memory.
const fs = require("fs");
const path = require("path");
// Read a file as a stream
const readStream = fs.createReadStream("large-file.csv", {
encoding: "utf8",
highWaterMark: 64 * 1024, // 64KB chunks
});
readStream.on("data", chunk => {
console.log("Received chunk:", chunk.length, "bytes");
});
readStream.on("end", () => console.log("File read complete"));
readStream.on("error", err => console.error("Error:", err));
// Write a file as a stream
const writeStream = fs.createWriteStream("output.txt");
writeStream.write("Line 1
");
writeStream.write("Line 2
");
writeStream.end("Final line
");const fs = require("fs");
const zlib = require("zlib");
// Compress a file — pipe readable through gzip into writable
fs.createReadStream("data.txt")
.pipe(zlib.createGzip())
.pipe(fs.createWriteStream("data.txt.gz"));
// Serve a large file from an HTTP server without loading it all into RAM
const http = require("http");
http.createServer((req, res) => {
res.writeHead(200, { "Content-Type": "video/mp4" });
fs.createReadStream("video.mp4").pipe(res);
}).listen(3000);