Bird
Raised Fist0
Node.jsframework~10 mins

Reading data with Readable streams in Node.js - Step-by-Step Execution

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Concept Flow - Reading data with Readable streams
Create Readable Stream
Attach 'data' event listener
Stream emits chunk
Receive chunk in listener
Process chunk (e.g., print or store)
Stream emits 'end'
Stop reading
Close stream
The flow shows creating a readable stream, listening for data chunks, processing each chunk, and stopping when the stream ends.
Execution Sample
Node.js
const fs = require('fs');
const stream = fs.createReadStream('file.txt');
stream.on('data', chunk => {
  console.log(chunk.toString());
});
stream.on('end', () => {
  console.log('Finished reading');
});
This code reads a file in chunks and prints each chunk until the file is fully read.
Execution Table
StepEvent EmittedChunk ContentAction TakenOutput
1dataHello Print chunkHello
2dataWorld!Print chunkWorld!
3endnullPrint finished messageFinished reading
4nonenullNo more data, stop readingStream closed
💡 Stream emits 'end' event, no more data to read
Variable Tracker
VariableStartAfter 1After 2After 3Final
chunkundefined"Hello ""World!"nullnull
stream.readableEndedfalsefalsefalsetruetrue
Key Moments - 3 Insights
Why do we get multiple 'data' events instead of one big chunk?
Because streams read data in small pieces (chunks) to avoid loading everything into memory at once, as shown in execution_table rows 1 and 2.
What does the 'end' event mean in the stream?
It means the stream has no more data to provide, so reading stops, as shown in execution_table row 3.
Why do we convert chunk to string before printing?
Chunks are Buffer objects by default; converting to string makes the data readable, as seen in the code sample.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, what is the chunk content at step 2?
A"World!"
B"Hello "
Cnull
D"Finished reading"
💡 Hint
Check the 'Chunk Content' column at step 2 in the execution_table.
At which step does the stream indicate it has finished reading?
AStep 1
BStep 2
CStep 3
DStep 4
💡 Hint
Look for the 'end' event in the 'Event Emitted' column in execution_table.
If the file was empty, which event would be emitted first?
A'data'
B'end'
C'error'
D'close'
💡 Hint
Refer to the concept_flow where 'end' means no data to read.
Concept Snapshot
Readable streams let you read data piece by piece.
Use 'data' event to get chunks as they arrive.
Use 'end' event to know when reading is done.
Chunks are Buffers; convert to string to read.
This helps handle large files without loading all at once.
Full Transcript
In Node.js, reading data with readable streams means you get data in small parts called chunks. You create a stream from a source like a file. Then you listen for 'data' events to receive chunks. Each chunk is a Buffer, so you convert it to string to see the content. When the stream finishes, it emits an 'end' event, telling you no more data is coming. This way, you can process large files efficiently without loading everything into memory at once.

Practice

(1/5)
1. What is the main purpose of a Readable stream in Node.js?
easy
A. To create a new HTTP server
B. To read data piece by piece without loading it all at once
C. To execute JavaScript code asynchronously
D. To write data to a file all at once

Solution

  1. Step 1: Understand what a Readable stream does

    A Readable stream reads data in small chunks instead of loading everything at once, which helps save memory.
  2. Step 2: Compare options with the purpose

    Only To read data piece by piece without loading it all at once describes reading data piece by piece, which matches the purpose of Readable streams.
  3. Final Answer:

    To read data piece by piece without loading it all at once -> Option B
  4. Quick Check:

    Readable stream = read data in chunks [OK]
Hint: Readable streams read data bit by bit, not all at once [OK]
Common Mistakes:
  • Confusing Readable streams with writing data
  • Thinking streams execute code
  • Mixing streams with server creation
2. Which of the following is the correct way to listen for data chunks from a Readable stream named stream?
easy
A. stream.on('data', chunk => { console.log(chunk); });
B. stream.emit('data', chunk => { console.log(chunk); });
C. stream.read('data', chunk => { console.log(chunk); });
D. stream.listen('data', chunk => { console.log(chunk); });

Solution

  1. Step 1: Recall the event listening method in Node.js streams

    To listen for events, use the on method with the event name and a callback function.
  2. Step 2: Match the correct syntax

    stream.on('data', chunk => { console.log(chunk); }); uses stream.on('data', callback), which is the correct way to listen for data chunks.
  3. Final Answer:

    stream.on('data', chunk => { console.log(chunk); }); -> Option A
  4. Quick Check:

    Use .on() to listen to stream events [OK]
Hint: Use .on('data', callback) to read chunks from streams [OK]
Common Mistakes:
  • Using emit instead of on to listen
  • Using non-existent methods like read or listen
  • Confusing event listening with emitting
3. What will the following code output if the file example.txt contains the text "Hello World"?
const fs = require('fs');
const stream = fs.createReadStream('example.txt');
stream.on('data', chunk => {
  console.log(chunk.toString());
});
stream.on('end', () => {
  console.log('Done reading');
});
medium
A. Hello World Done reading
B. Buffer data Done reading
C. Hello WorldDone reading
D. SyntaxError

Solution

  1. Step 1: Understand the stream reading process

    The stream reads the file in chunks and emits 'data' events. Each chunk is a Buffer, converted to string with toString().
  2. Step 2: Analyze the output

    The console logs the text "Hello World" followed by a newline, then logs "Done reading" when the stream ends.
  3. Final Answer:

    Hello World Done reading -> Option A
  4. Quick Check:

    Stream reads text chunks and logs 'Done reading' at end [OK]
Hint: Streams emit 'data' chunks as Buffers; convert to string to read [OK]
Common Mistakes:
  • Expecting raw Buffer output without conversion
  • Missing the 'end' event message
  • Confusing output formatting
4. Identify the error in this code snippet that reads data from a stream:
const fs = require('fs');
const stream = fs.createReadStream('file.txt');
stream.on('data', (chunk) => {
  console.log(chunk);
});
stream.on('finish', () => {
  console.log('Stream finished');
});
medium
A. The 'data' event callback is missing a parameter
B. The stream should be paused before reading
C. The 'finish' event does not exist on Readable streams
D. The file path must be absolute

Solution

  1. Step 1: Check event names for Readable streams

    Readable streams emit 'end' when done, not 'finish'. 'finish' is for Writable streams.
  2. Step 2: Identify the incorrect event usage

    The code listens for 'finish', which will never fire on a Readable stream, causing the message to never appear.
  3. Final Answer:

    The 'finish' event does not exist on Readable streams -> Option C
  4. Quick Check:

    Readable streams use 'end', not 'finish' event [OK]
Hint: 'finish' is for writing; use 'end' for reading streams [OK]
Common Mistakes:
  • Using 'finish' event on Readable streams
  • Forgetting to handle 'end' event
  • Assuming 'data' event has no parameters
5. You want to read a large file using a Readable stream and count how many times the word "node" appears, case-insensitive. Which approach correctly handles data chunks to count occurrences without missing matches across chunk boundaries?
hard
A. Convert each chunk to string and count occurrences immediately, ignoring chunk edges
B. Count occurrences in each chunk separately without storing leftover text
C. Use a writable stream instead of a readable stream for counting
D. Concatenate chunks into a string, then count occurrences after 'end' event

Solution

  1. Step 1: Understand chunk boundaries in streams

    Chunks may split words, so counting in each chunk separately can miss matches that cross chunk edges.
  2. Step 2: Choose a method to avoid missing matches

    Concatenating all chunks into one string and counting after the 'end' event ensures all occurrences are counted correctly.
  3. Final Answer:

    Concatenate chunks into a string, then count occurrences after 'end' event -> Option D
  4. Quick Check:

    Count after full data read to avoid split word misses [OK]
Hint: Join chunks first, then count words to avoid split matches [OK]
Common Mistakes:
  • Counting words in each chunk ignoring splits
  • Using writable streams for reading tasks
  • Not handling case-insensitive matching