Node.js中你不可不精的Stream(流)(2)


在文件看来,它的内容被分块地连续取走了。

在下游看来,它收到的是一个先后到达的数据序列。

如果不需要一次操作全部内容,它可以处理完一个数据便丢掉。

在流看来,任一时刻它都只存储了文件中的一部分数据,只是内容在变化而已。

这种情况就像是用水管去取池子中的水。

每当用掉一点水,水管便会从池子中再取出一点。

无论水池有多大,都只存储了与水管容积等量的水。

Exp2:

下面是一个在线看视频的例子,假定我们通过HTTP请求返回视频内容给用户

const http = require('http');
const fs = require('fs');
 
http.createServer((req, res) => {
 fs.readFile(videoPath, (err, data) => {
 res.end(data);
});
}).listen(8080);

但这样有两个明显的问题

  • 视频文件需要全部读取完,才能返回给用户,这样等待时间会很长。
  • 视频文件一次全放入内存中,内存吃不消。

用流可以将视频文件一点一点读到内存中,再一点一点返回给用户,读一部分,写一部分。(利用了 HTTP 协议的 Transfer-Encoding: chunked 分段传输特性),用户体验得到优化,同时对内存的开销明显下降。

const http = require('http');
const fs = require('fs');
 
http.createServer((req, res) => {
 fs.createReadStream(videoPath).pipe(res);
}).listen(8080);

通过上述两个例子,我们知道,在大数据情况下必须使用流式处理。

四、可读流(Readable Stream)

可读流(Readable streams)是对提供数据的源头(source)的抽象。

常见的可读流:

  • HTTP responses, on the client
  • HTTP requests, on the server
  • fs read streams
  • TCP sockets //sockets是一个双工流,即可读可写的流
  • process.stdin //标准输入

所有的 Readable Stream 都实现了 stream.Readable 类定义的接口。

可读流的两种模式(flowing 和 paused)

  • 在 flowing 模式下,可读流自动从系统底层读取数据,并通过 EventEmitter 接口的事件尽快将数据提供给应用(所有的流都是 EventEmitter 的实例)。
  • 在 paused 模式下,必须显式调用 stream.read()方法来从流中读取数据片段。

创建流的Readable流,默认是非流动模式(paused模式),默认不会读取数据。所有初始工作模式为paused的Readable流,可以通过下面三种途径切换为flowing模式:

  • 监听'data'事件
  • 调用stream.resume()方法
  • 调用stream.pipe()方法将数据发送到Writable

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/68.html