RSSAmplifier

DanLevy.net · Nov 15, 2024

Quiz: NodeJS IO Mastery

0
Sign in to vote or save

Dan Levy · danlevy.net

Test your knowledge of files, streams & buffers

Ready to dive into the world of NodeJS IO? 🌊

This quiz will test your understanding of Node’s IO operations, from basic file system operations to advanced streaming concepts. We’ll cover buffers, encoding, and best practices for handling data efficiently.

Let’s see how well you know your streams from your buffers! 🚀

What does this code do?

const buf = Buffer.alloc(5);

console.log(buf);

Buffer.alloc(size) creates a new Buffer of specified size filled with zeros. The output will be: <Buffer 00 00 00 00 00>

If you want to create a Buffer with random data, use Buffer.allocUnsafe(5).

Learn more about Buffer allocation

Creates a Buffer of size 5 with zeros

Creates a Buffer of size 5 with random data

Throws an error

Creates an empty Buffer

What will this print?

const buf = Buffer.from([65]);

console.log(buf.toString());

The numbers in the array represent ASCII codes:

  • 65: ‘A’

toString() converts these bytes to their string representation using UTF-8 encoding by default.

Learn more about Buffer encoding

A

65

[Object object]

Undefined

Binary data

What’s the output order?

import fs from 'fs';

fs.readFile('test.txt', 'utf8', (err, data) => {

console.log(data);

});

console.log('Done');

Since readFile is asynchronous, the code continues executing while the file is being read. Therefore, “Done” will be printed before the file content.

To wait for the file to be read first, you could use the Promise-based version:

import { promises as fs } from 'fs';

async function read() {

const data = await fs.readFile('test.txt', 'utf8');

console.log(data);

console.log('Done');

}

Prints file content then "Done"

Prints "Done" then file content

Only prints file content

Throws an error

What does fs.readFileSync() return by default?

import fs from 'fs';

const content = fs.readFileSync('test.txt');

fs.readFileSync() returns a Buffer by default when no encoding is specified. If you want a string, you need to either:

  1. Specify an encoding: fs.readFileSync('test.txt', 'utf8')
  2. Convert the Buffer: content.toString()

Learn more about fs.readFileSync on Node.js docs

Returns a Buffer

Returns a string

Returns undefined

Returns a Promise

Which set of events are commonly used with Readable streams?

Readable streams emit several important events:

  • ‘data’: When data is available to be read
  • ‘end’: When there is no more data to read
  • ‘error’: When an error occurs
  • ‘close’: When the stream and underlying resource have closed

const readable = fs.createReadStream('file.txt');

readable.on('data', chunk => console.log(chunk));

readable.on('end', () => console.log('Done!'));

Learn more about Stream events

'data', 'end', 'error', 'close'

'finish', 'drain', 'pipe'

'read', 'write', 'end'

'open', 'close', 'data'

What does this code do?

import fs from 'fs';

const readable = fs.createReadStream('source.txt');

const writable = fs.createWriteStream('dest.txt');

readable.pipe(writable);

pipe() connects a readable stream to a writable stream, automatically managing backpressure and copying data in chunks without loading the entire file into memory.

This is memory-efficient for large files compared to fs.readFile() followed by fs.writeFile().

Learn more about pipe()

Copies file with compression

Copies file without memory buffering

Loads entire file into memory

Creates a symbolic link

What does the recursive option do?

import fs from 'fs';

fs.mkdirSync('./a/b/c', { recursive: true });

The recursive: true option creates parent directories if they don’t exist. Without this option, trying to create ’./a/b/c’ would throw an error if ’./a’ or ’./a/b’ don’t exist.

This is similar to the shell command mkdir -p.

Learn more about mkdir

Creates nested directories if needed

Creates only the last directory

Throws an error

Creates symbolic links

What will this output?

import { Transform } from 'stream';

const upperCase = new Transform({

transform(chunk, encoding, callback) {

callback(null, chunk.toString().toUpperCase());

}

});

process.stdin

.pipe(upperCase)

.pipe(process.stdout);

// Input: "hello world"

Transform streams modify data as it passes through. Here, each chunk is:

  1. Converted to a string
  2. Transformed to uppercase
  3. Passed to stdout

This creates a pipeline that converts all input to uppercase.

Learn more about Transform streams

hello world

HELLO WORLD

Error

undefined

How many times is fs.watch() guaranteed to fire when a file is modified?

import fs from 'fs';

fs.watch('test.txt', (eventType, filename) => {

console.log(`${filename} was changed`);

});

// Then modify test.txt once

fs.watch() is not guaranteed to fire exactly once per logical file change. It often fires multiple times because many text editors:

  1. Save to a temporary file
  2. Rename it to the target file

For more reliable watching, consider using:

  • The chokidar package
  • Debouncing the callback
  • Using fs.watchFile() (though it’s less efficient)

Learn more about fs.watch()

Once per file change

Not guaranteed; may fire multiple times

Never

Only on file deletion

What’s the output?

const buf1 = Buffer.from('Hello');

const buf2 = Buffer.from('Hello');

console.log(buf1 === buf2);

Buffers are compared by reference, not value. Even though they contain the same data, they are different objects.

To compare Buffer contents, use:

buf1.equals(buf2) // true

// or

Buffer.compare(buf1, buf2) === 0 // true

Learn more about Buffer comparison

true

false

undefined

Error

What’s the main purpose of stream backpressure?

Backpressure is a mechanism that prevents memory overflow by pausing reading when the writing end can’t keep up.

Example of manual backpressure:

readable.on('data', (chunk) => {

const canContinue = writable.write(chunk);

if (!canContinue) {

readable.pause();

writable.once('drain', () => readable.resume());

}

});

pipe() handles this automatically!

Learn more about backpressure

Prevents memory overflow

Increases read speed

Compresses data

Encrypts data

What does this code do?

import fs from 'fs';

fs.symlinkSync('target.txt', 'link.txt');

symlinkSync creates a symbolic link (like a shortcut) to the target file.

Key differences from hard links:

  • Can link to directories
  • Can span file systems
  • Breaks if target is deleted

To create a hard link instead:

fs.linkSync('target.txt', 'hardlink.txt');

Learn more about symlinks

Creates a hard link

Creates a copy

Creates a symbolic link

Moves the file

What modes can Node.js streams operate in?

Streams can operate in:

  1. Binary mode (default): for buffers and strings
  2. Object mode: for any JavaScript value

Example of object mode:

import { Transform } from 'stream';

const objectStream = new Transform({

objectMode: true,

transform(chunk, encoding, callback) {

callback(null, { value: chunk });

}

});

Learn more about stream modes

Binary mode only

Object mode only

Both modes

Neither mode

Input & output modes

Read & write modes

What type is the fd parameter in this callback?

import fs from 'fs';

fs.open('test.txt', 'r', (err, fd) => {

console.log(typeof fd);

});

File descriptors are numbers that uniquely identify open files in the operating system.

The first three file descriptors are reserved:

  • 0: stdin
  • 1: stdout
  • 2: stderr

Always remember to close file descriptors:

fs.close(fd, (err) => {

if (err) throw err;

});

Learn more about file descriptors

A number

A string

An object

A buffer

How many bytes will this string take in UTF-8?

const str = "Hello 🌍";

const buf = Buffer.from(str);

console.log(buf.length);

In UTF-8:

  • ASCII characters (like ‘Hello ’) take 1 byte each
  • The earth emoji 🌍 takes 4 bytes

So: 5 (Hello) + 1 (space) + 4 (🌍) = 10 bytes

To see the bytes:

console.log(buf); // <Buffer 48 65 6c 6c 6f 20 f0 9f 8c 8d>

Learn more about UTF-8 encoding

3

4

6

8

10

I hope you enjoyed testing your NodeJS IO knowledge! Want more? Check out my Quiz Collection for more challenges!

Read the original on danlevy.net

Comments

Nothing yet. Say the first thing.

    Sign in to join the conversation.