Stream文件流
Stream文件流
由于Buffer缓冲区限制在1GB,超过1GB的文件无法直接完成读/写操作,在读/写大文件时,如果读/写资源一直持续不停止,Node.js将无法继续其他工作。为此,Node.js中提供了Stream文件流模块,用来解决大数据文件操作的问题。
文件流的概念
Node.js的File System模块并没有提供一个 copy的方法,但是通过读取文件和写人文件的方式可以实现,即把文件A的内容全部读入Buffer缓冲区,然后再从缓冲区读出写人文件B,该过程的执行流程图如下图所示。
在上图中,可以看出要读取数据需要存放到Buffer缓冲区中,然后再从缓冲区读出写入到文件,Buffer缓冲区限制在1GB,这样的操作对于小型的文本文件,没有多大问题,但是对于体积较大的文件,比如音频、视频文件,动辄几吉字节大小,如果使用理想的方法,很容易使内存“爆仓”。理想的方法应该是读一部分,写一部分,不管文件有多大,只要时间允许,总会处理完成,这里就需要用到流的概念,文件复制操作使用文件流的读/写机制进行会防止“爆仓”现象的出现,流程如图所示。
在上图中可以看到,文件A中数据以流动的形式通过数据流管道,然后进入到文件B中,采用“读一部分,写 一部分”的方式。流的好处是接收方可以提前处理,缩短等待时间,提高速度。例如,在网络上观看视频,并不是整个视频下载好了才播放的,而是下一.点播一点。
在Node.js中,文件流的操作由Stream模块提供,Stream 是一个抽象接口, Node.js中还有很多对象实现了这个接口。例如,对HTTP服务器发起请求的request对象就是一个Stream,还有stdout (标准输出)等。
Node.js中,Stream 有4种流类型:
- Readable: 可读操作(可读流)。
- Writable: 可写操作(可写流)。
- Duplex: 可读可写操作(双向流、双工流)。
- Transform: 操作被写人数据,然后读出结果(变换流)。
在Node.js中,很多模块涉及流的读/写,例如,HTTP requests and responses. Standard input/output、File reads and writes。Node.js 中的I/O是异步的,因此对磁盘和网络的读/写需要通过回调函数来读取数据,而回调函数需要通过事件来触发,所有的Stream对象都是EventEmitter (时间触发器)的实例。常用的事件如下表所示。
事件 | 说明 |
---|---|
data | 当有数据可读时触发 |
end | 没有更多的数据可读时触发 |
error | 在接收和写入过程中发生错误时触发 |
finish | 有数据已被写入到底层系统时触发 |