概述
Node.js 的可读流(Readable Stream)是一种可以从源头读取数据的抽象接口。这些流可以用于处理大量数据或实时数据流,例如从网络接收数据、文件系统读取文件或处理数据库查询结果等。
创建可读流
内置的可读流
Node.js 提供了一些内置的可读流类,如 fs.ReadStream 和 http.IncomingMessage。这些流可以直接使用而无需额外配置。
const fs = require('fs');
// 使用 fs.createReadStream 创建一个可读流
const readStream = fs.createReadStream('./example.txt');自定义可读流
除了使用内置流之外,还可以通过继承 stream.Readable 类来创建自定义的可读流。
// www.javascriptcn.com code example
const { Readable } = require('stream');
class CustomReadable extends Readable {
constructor(options) {
super(options);
this.data = ['Hello', 'World'];
this.index = 0;
}
_read() {
if (this.index === this.data.length) {
this.push(null);
return;
}
const chunk = this.data[this.index++];
this.push(chunk + '\n');
}
}
const customStream = new CustomReadable();
customStream.pipe(process.stdout);流事件
可读流主要涉及以下几种事件:
- data:当有数据可用时触发。
- end:当没有更多数据可读时触发。
- error:当发生错误时触发。
- close:当流关闭时触发。
// www.javascriptcn.com code example
const fs = require('fs');
const readStream = fs.createReadStream('./example.txt');
readStream.on('data', (chunk) => {
console.log(`Received ${chunk.length} bytes of data.`);
});
readStream.on('end', () => {
console.log('There will be no more data.');
});
readStream.on('error', (err) => {
console.error(`Error: ${err.message}`);
});高级流操作
流的管道
管道(pipe)是将一个流的数据输出到另一个流的操作。这使得数据可以在不同的流之间无缝传输,而不需要手动处理缓冲区和数据分段。
const fs = require('fs');
const readStream = fs.createReadStream('./source.txt');
const writeStream = fs.createWriteStream('./destination.txt');
readStream.pipe(writeStream);限制流速度
可以通过设置 highWaterMark 参数来限制流的速度,从而避免内存溢出。
// www.javascriptcn.com code example
const { Readable } = require('stream');
class LimitedReadable extends Readable {
constructor(options) {
super({ highWaterMark: 3, ...options });
this.counter = 0;
}
_read() {
if (this.counter >= 6) {
this.push(null);
return;
}
this.push(`${this.counter}\n`);
this.counter++;
}
}
const limitedStream = new LimitedReadable();
limitedStream.pipe(process.stdout);流的转换
通过使用 Transform 类,可以创建能够同时读写数据的流。这对于需要对数据进行转换的场景非常有用。
// www.javascriptcn.com code example
const { Transform } = require('stream');
class UpperCaseTransform extends Transform {
_transform(chunk, encoding, callback) {
this.push(chunk.toString().toUpperCase());
callback();
}
}
const transformStream = new UpperCaseTransform();
process.stdin.pipe(transformStream).pipe(process.stdout);总结
通过上述介绍,我们了解了 Node.js 中可读流的基本概念及其使用方法。可读流不仅提供了高效的数据处理机制,还为开发者提供了丰富的功能和灵活性。掌握这些基础知识对于开发高性能的网络应用和数据处理工具至关重要。