可读流(Readable Stream)
- 特点:用于从源读取数据,数据流向是从底层系统到应用程序。有两种模式:暂停模式和流动模式。暂停模式下,需要手动调用
read()
方法来读取数据;流动模式下,数据会自动流动,通过 data
事件来监听数据。
- 适用场景:读取大文件,例如读取一个非常大的日志文件,以流的方式读取可以避免一次性将整个文件加载到内存中,减少内存压力。示例代码如下:
const fs = require('fs');
const readableStream = fs.createReadStream('largeFile.log');
readableStream.on('data', (chunk) => {
console.log('Received chunk:', chunk.length);
});
readableStream.on('end', () => {
console.log('All data has been read.');
});
可写流(Writable Stream)
- 特点:用于向目标写入数据,数据流向是从应用程序到底层系统。可以通过
write()
方法写入数据,写完后调用 end()
方法。通过 drain
事件可以知道缓冲区是否有空间继续写入数据。
- 适用场景:写入大文件,比如将大量数据写入到日志文件中。示例代码如下:
const fs = require('fs');
const writableStream = fs.createWriteStream('output.log');
const data = 'This is some data to write to the file';
writableStream.write(data);
writableStream.end();
writableStream.on('finish', () => {
console.log('Data has been written successfully.');
});
双工流(Duplex Stream)
- 特点:同时具备可读流和可写流的功能,既可以读取数据也可以写入数据。数据可以在两个方向上流动,像
net.Socket
就是一个双工流的例子,既能发送数据也能接收数据。
- 适用场景:网络通信场景,例如创建一个简单的TCP服务器,服务器端的套接字(socket)可以同时发送和接收数据。示例代码如下:
const net = require('net');
const server = net.createServer((socket) => {
socket.write('Welcome!\n');
socket.on('data', (data) => {
socket.write('You sent: ' + data);
});
socket.on('end', () => {
console.log('Client disconnected');
});
});
server.listen(3000, () => {
console.log('Server listening on port 3000');
});
转换流(Transform Stream)
- 特点:继承自双工流,在读写数据的过程中对数据进行转换处理。数据在写入和读取之间会经过转换操作。例如
zlib
模块中的压缩和解压缩流就是转换流,在写入数据时进行压缩,读取时进行解压缩。
- 适用场景:数据处理场景,比如对读取的文件内容进行加密后再写入到另一个文件。示例代码如下:
const { Transform } = require('stream');
const fs = require('fs');
// 创建一个简单的转换流,将输入字符串转换为大写
const upperCaseTransform = new Transform({
transform(chunk, encoding, callback) {
const upperCaseChunk = chunk.toString().toUpperCase();
callback(null, upperCaseChunk);
}
});
const readableStream = fs.createReadStream('input.txt');
const writableStream = fs.createWriteStream('output.txt');
readableStream.pipe(upperCaseTransform).pipe(writableStream);