In this lesson, you will learn how to turn sporadic file system events into a continuous flow of data using readable streams, allowing you to process file changes as a reactive pipeline.
Bridging Events and Streams
Normally, when you watch a folder with fs.watch, you receive individual events whenever a file is created or modified. While useful, this approach can quickly lead to "callback hell" if you need to perform complex tasks like validation, compression, or transformation on these files. By wrapping these events in a Readable stream, we can treat file system changes as a unified stream of data that flows through a pipeline.
Creating a Reactive File Watcher
To achieve this, we create a Readable stream that emits file paths whenever an event occurs. By pushing these paths into the stream, we can connect the file watcher directly to our existing stream processing architectures.
const { Readable } = require('stream');
const fs = require('fs');
function createWatcherStream(directory) {
return new Readable({
objectMode: true, // We are passing file paths, not binary buffers
read() {} // No-op: we push data manually when events occur
});
}
const watcherStream = createWatcherStream('./uploads');
fs.watch('./uploads', (eventType, filename) => {
if (filename) {
// Push the event into our stream pipeline
watcherStream.push({ eventType, filename });
}
});
Why Use Streams Here?
By transforming events into a stream, you can immediately utilize the concepts we’ve mastered, such as Pipeline Helpers and Transform Streams.
Instead of writing a manual handler for every file change, you can pipe your watcherStream into a Transform stream that reads the file content, another that performs encryption or compression, and a final Writable stream that saves the result to a database or cloud storage. This decouples the "detection" of the file from the "processing" logic, making your architecture highly modular. You gain the benefit of automatic backpressure management: if your processing logic is slow, the stream effectively manages the flow, preventing your system from becoming overwhelmed by a burst of file system events.
Key Takeaway: By wrapping file system events in a Readable stream, you turn erratic triggers into a controllable, backpressure-aware data flow that fits perfectly into your existing stream pipelines.