什么是流「Stream」?如何理解Nodejs中的流

1. 流(Stream)是什么?

流(Stream)在计算机科学中是一种抽象的数据结构,它是有序的、可重复读取的字节序列。流可以是输入流、输出流或双向流,它们对应的抽象数据类型分别为InputStream、OutputStream和Stream。

在Node.js中,流是一个非常重要的概念,这是因为Node.js是基于事件驱动的非阻塞I/O模型,而流能够协助我们处理I/O操作,从而提升Node.js的性能和效率。

2. Node.js中的流

2.1 可读流

可读流(Readable Stream)是Node.js中的一个重要概念。它是用来读取数据的流,在Node.js中,可读流的实现是基于stream.Readable。

在使用可读流时,需要调用readable流上的read方法来开始读取数据。read方法能够从stream.Readable内部的缓冲区中读取一定长度的数据,并将其返回。如果可读流中没有数据可供读取,则read方法会返回一个null值,以此来指示数据已经全部读取完成。

const { Readable } = require('stream');

const readable = new Readable({

read() {

this.push('Hello, ');

this.push('world!');

this.push(null);

}

});

readable.on('data', (chunk) => {

console.log(chunk.toString());

});

// Output: Hello, world!

上述代码演示的是一个简单的可读流操作。readable流的read方法返回的是“Hello, ”和“world!”两个数据块。当这些数据块被读取时,会通过data事件进行传递。

2.2 可写流

可写流(Writable Stream)是Node.js中的另一个重要概念。它是用来写入数据的流,在Node.js中,可写流的实现是基于stream.Writable。

在使用可写流时,需要调用writable流上的write方法来写入数据。write方法能够将数据写入可写流内部的缓冲区,并返回一个Boolean值,用来指示缓冲区是否已经满了。如果缓冲区已经满了,则write方法会返回false,并在缓冲区有足够空间后再次尝试写入数据。当所有数据块都被写入完成时,需要调用writable流上的end方法来结束可写流的操作。

const { Writable } = require('stream');

const writable = new Writable({

write(chunk, encoding, callback) {

console.log(chunk.toString());

callback();

}

});

writable.write('Hello, ');

writable.write('world!');

writable.end();

// Output: Hello, world!

上述代码演示的是一个简单的可写流操作。通过writable流的write方法,将“Hello, ”和“world!”两个数据块写入可写流中,当这些数据块被写入时,会通过writable流中的write方法进行处理。在所有数据块被写入完成后,通过writable流的end方法来结束流操作。

2.3 双向流

双向流(Duplex Stream)在Node.js中也是一种非常常见的流类型。双向流可以同时实现可读流和可写流的功能,也可以同时进行数据的读取和写入。

在Node.js中,双向流的实现是基于stream.Duplex。与可读流和可写流不同的是,双向流需要同时实现_read和_write方法来完成读取和写入操作。

const { Duplex } = require('stream');

const duplex = new Duplex({

read(size) {

if (this.currentCharCode > 90) {

this.push(null);

return;

}

this.push(String.fromCharCode(this.currentCharCode++));

},

write(chunk, encoding, callback) {

console.log(chunk.toString());

callback();

}

});

duplex.currentCharCode = 65;

setInterval(() => {

duplex.write(String.fromCharCode(duplex.currentCharCode++));

}, 100);

duplex.pipe(process.stdout);

上述代码演示的是一个简单的双向流操作。通过duplex流的_read方法,每隔100毫秒将一个字母内容写入可写流中;通过duplex流的_write方法,将双向流中的数据块进行处理。通过pipe方法来将双向流与process.stdout进行连接,从而将所有数据块都输出到控制台中。

3. 流操作的优势和应用场景

流的出现为Node.js带来了很多优势,主要包括以下几点:

3.1 内存占用少

通过流操作能够做到以流的形式处理大型文件数据,而无需将所有数据块全部读取到内存中。这样可以减少对内存的占用,更好地处理大型文件数据。

3.2 提升性能

通过流操作能够通过异步方式来进行数据的读取和写入,从而提升Node.js的I/O操作性能。

3.3 适用于处理大文件

当处理大文件时,流操作可以避免在内存中同时读取整个文件,并且可以通过将文件内容按照流的方式进行切割,使得有序、逐段地对文件进行处理,节省更多内存。而且,在Node.js中,流操作是一种非常高效的处理大文件的方式。

综上所述,流是Node.js中一个重要的概念。虽然它有一定的学习成本,但是它能够极大地提升Node.js的性能和处理大型文件数据的能力,值得我们深入学习和使用。

免责声明:本文来自互联网,本站所有信息(包括但不限于文字、视频、音频、数据及图表),不保证该信息的准确性、真实性、完整性、有效性、及时性、原创性等,版权归属于原作者,如无意侵犯媒体或个人知识产权,请来电或致函告之,本站将在第一时间处理。猿码集站发布此文目的在于促进信息交流,此文观点与本站立场无关,不承担任何责任。