给大家解答下Node中的Stream流
Node中的Stream+流
在Node中,Stream是一种处理数据的方式,它可以让我们以流式的方式进行数据处理,而不是一次性地读入整个文件或数据,特别适合处理大文件或需要实时处理的数据。Stream接口实现了Unix的I\/O哲学:一切皆为文件,输入和输出被抽象为可读、可写或可读写的流。Node中的所有Stream都是EventEmitter的实例,具有统一的接口。
可写流
可写流是一种输出数据的机制,常用于写文件或向HTTP响应发送数据。当我们使用可写流的时候,数据被分为小块且逐块发送出去,这可以提高处理大量数据的性能。下面是一个创建和写入可写流的例子:
const fs = require('fs'); const writableStream = fs.createWriteStream('output.txt'); const data = 'Hello, World!'; writableStream.write(data); writableStream.end();
通过上述代码,我们创建了一个可写流,并将“Hello, World”写入到文件output.txt中,然后通过调用end()方法,结束写入。在写入数据的时候,底层机制会将数据分成小块,然后将小块写入到输出流中。
可读流
可读流是一种输入数据的机制,常用于读取文件或从HTTP请求中读取数据。当我们使用可读流的时候,它会自动读取数据并分成小块进行传输,直到所有数据都被完全读取。下面是一个从文件中读取数据的例子:
const fs = require('fs'); const readableStream = fs.createReadStream('input.txt'); let data = ''; readableStream.on('data', chunk => { data += chunk; }); readableStream.on('end', () => { console.log(data); });
通过上述代码,我们创建了一个可读流,并从文件input.txt中读取数据。在每次读取数据的时候,底层机制会将数据分成小块,并通过监听data事件返回每个小块数据的缓冲区,这样我们就可以逐条读取数据。在所有数据都被读取之后,通过监听end事件来确定所有数据都已被完全读取。
管道流
管道流是一种将可读流和可写流连接起来的机制,它自动将可读流的每个数据块写入可写流中。这样我们就可以快速完成从输入到输出的数据传输。下面是一个选择CSV中某些列并将其写入另一个CSV文件的例子:
const csv = require('csv-parser'); const fs = require('fs'); const ws = fs.createWriteStream('output.csv'); fs.createReadStream('input.csv') .pipe(csv()) .on('data', row => { const { column1, column3 } = row; ws.write([column1, column3].join(',') + '\n'); }) .on('end', () => { console.log('Done'); ws.end(); });
通过上述代码,我们将输入CSV文件传入一个csv-parser中间件,然后在每个数据块通过解构选取部分列到新的可写流。管道流自动输入这些块,由新的可写流自动编排为正确格式的CSV文件。
总结: 在Node中,Stream是一种实现Unix I/O哲学的数据处理方式,对于大量数据的处理非常高效。可写流可以将数据打包为小块实时输出数据,可读流可以将数据自动读取并发送缓冲块,管道流可以将可读和可写流连接起来自动传输数据。在处理文件、HTTP请求和流处理等方面,Node中的Stream流机制具有重要的作用。