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