Node.js Stream(流)


Node.js Stream(流)

概述

流(Stream)在 Node.js 中是非常重要的概念,它是一种处理流式数据的抽象接口。在 Node.js 中,有很多内置的模块都是基于流来实现的,如httpfsprocess.stdin等。

流的类型

Node.js中可以处理的流大致可以分为四种类型:

可读流

可读流是指通过流传输数据时,数据从某个地方进入到 Node.js 应用程序中。例如,从本地文件系统中读取一个文件,或从网络中接收一个 HTTP 响应。

在 Node.js 中,大部分可读流都继承于Readable类,它是一个抽象基类。在使用可读流时,通常需要实现Readable类中定义的抽象方法:_read()方法。该方法的作用是返回一定量的数据,供应用程序使用。

可写流

可写流是指通过流传输数据时,数据从 Node.js 应用程序输出到某个地方。例如,将数据写入本地文件系统中,或将数据发送到外部服务器。

在 Node.js 中,大部分可写流都继承于Writable类,它是一个抽象基类。在使用可写流时,通常需要实现Writable类中定义的抽象方法:_write()方法。该方法接收应用程序提供的数据,并将其写入到可写流中。

双工流

双工流是一个同时可读可写的流。例如,当应用程序向外部服务器发送数据时,它可以在同一时间从该服务器接收数据。

在 Node.js 中,大部分双工流都继承于Duplex类,它是一个抽象基类。在使用双向流时,通常需要实现Duplex类中定义的抽象方法:_read()_write()方法。

转换流

转换流是指一个特殊的双工流,其输入和输出是经过某些处理的。例如,在处理一个压缩文件时,可以使用转换流来解压缩数据。

在 Node.js 中,大部分转换流都继承于Transform类,它是一个抽象基类。在使用转换流时,通常需要实现Transform类中定义的抽象方法:_transform()_flush()方法。前者将输入数据进行处理,后者在结束流时清空缓存区。

读写流

在使用流时,经常需要同时使用可读流和可写流。例如,将一个数据库表中的数据导出成一个 CSV 文件,我们需要从数据库中读取数据,并将其写入到文件中。

在 Node.js 中,可以使用pipe()方法来连接一个可读流和一个可写流。该方法会自动将可读流中的数据传递给可写流,直到可读流读取完毕为止。

const fs = require('fs');
const rs = fs.createReadStream('./source.txt');
const ws = fs.createWriteStream('./target.txt');

rs.pipe(ws);

同样,可以将一个转换流放在中间,来实现数据的处理。

const fs = require('fs');
const zlib = require('zlib');
const rs = fs.createReadStream('./source.txt');
const ws = fs.createWriteStream('./target.txt.gz');

rs.pipe(zlib.createGzip()).pipe(ws);

总结

Node.js 中的流是一种非常重要的概念,它是一种处理流式数据的抽象接口。在 Node.js 中,有四种类型的流:可读流、可写流、双工流和转换流。在使用流时,通常需要同时使用可读流和可写流,并使用pipe()方法将它们连接起来。