MST
星途 面试题库

面试题:Node.js中Stream流的基本类型及应用场景

请简述Node.js中Stream流有哪几种基本类型,每种类型的特点是什么,并举例说明它们各自适用于哪些应用场景。
11.6万 热度难度
前端开发Node.js

知识考点

AI 面试

面试题答案

一键面试

可读流(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);