Advanced Node.js

Master advanced Node.js concepts including microservices, performance optimization, and production deployment.

advanced Backend Development 7 hours

Chapter 3: Streams and Buffers Advanced

Chapter 3 of 15

Chapter 3: Streams and Buffers Advanced

3.1 Stream Types

Streams are objects that let you read data from a source or write data to a destination in a continuous fashion. They're essential for handling large amounts of data efficiently.

Stream Types:

  • Readable: Can read data from (e.g., fs.createReadStream)
  • Writable: Can write data to (e.g., fs.createWriteStream)
  • Duplex: Both readable and writable (e.g., net.Socket)
  • Transform: Duplex stream that can modify data (e.g., zlib.createGzip)
// Readable stream
const fs = require('fs');
const readable = fs.createReadStream('large-file.txt');

readable.on('data', (chunk) => {
    console.log(`Received ${chunk.length} bytes`);
});

readable.on('end', () => {
    console.log('Finished reading');
});

// Writable stream
const writable = fs.createWriteStream('output.txt');

writable.write('Hello World
');
writable.write('Another line
');
writable.end('Final line');

3.2 Piping Streams

// Pipe readable to writable
const fs = require('fs');
const zlib = require('zlib');

fs.createReadStream('input.txt')
    .pipe(zlib.createGzip())
    .pipe(fs.createWriteStream('input.txt.gz'));

// Error handling in pipes
const stream = fs.createReadStream('input.txt')
    .on('error', (err) => {
        console.error('Read error:', err);
    })
    .pipe(zlib.createGzip())
    .on('error', (err) => {
        console.error('Compress error:', err);
    })
    .pipe(fs.createWriteStream('output.gz'))
    .on('error', (err) => {
        console.error('Write error:', err);
    });

3.3 Custom Streams

const { Readable, Writable, Transform } = require('stream');

// Custom readable stream
class MyReadable extends Readable {
    constructor(options) {
        super(options);
        this.count = 0;
    }
    
    _read() {
        if (this.count++ < 10) {
            this.push(`Data chunk ${this.count}
');
        } else {
            this.push(null); // End stream
        }
    }
}

// Custom transform stream
class UpperCaseTransform extends Transform {
    _transform(chunk, encoding, callback) {
        this.push(chunk.toString().toUpperCase());
        callback();
    }
}

// Usage
const readable = new MyReadable();
const transform = new UpperCaseTransform();
const writable = fs.createWriteStream('output.txt');

readable.pipe(transform).pipe(writable);

3.4 Buffers

// Creating buffers
const buf1 = Buffer.from('Hello');
const buf2 = Buffer.alloc(10); // 10 bytes initialized to 0
const buf3 = Buffer.allocUnsafe(10); // Faster but may contain old data

// Buffer operations
const buf = Buffer.from('Hello World');
console.log(buf.toString()); // "Hello World"
console.log(buf.toString('base64')); // Base64 encoding
console.log(buf.length); // 11

// Buffer concatenation
const buf4 = Buffer.concat([buf1, buf2]);

// Buffer comparison
buf1.compare(buf2); // Returns -1, 0, or 1