简单理解:
我们可以把整个流(stream)和 buffer 的配合过程看作公交站。在一些公交站,公车在没有装满乘客前是不会发车的,或者在特定的时刻才会发车。当然,乘客也可能在不同的时间,人流量大小也会有所不同,有人多的时候,有人少的时候,乘客或公交站都无法控制人流量。不论何时,早到的乘客都必须等待,直到公车接到指令可以发车。当乘客到站,发现公车已经装满,或者已经开走,他就必须等待下一班车次。
典型的例子:
就是你在线看视频的时候。如果你的网络足够快,数据流(stream)就可以足够快,可以让 buffer 迅速填满然后发送和处理,然后处理另一个,再发送,再另一个,再发送,然后整个 stream 完成。
但是当你网络连接很慢,当处理完当前的数据后,你的播放器就会暂停,或出现”缓冲”(buffer)字样,意思是正在收集更多的数据,或者等待更多的数据到来,才能下一步处理。当buffer装满并处理好,播放器就会显示数据,也就是播放视频了。在播放当前内容的时候,更多的数据也会源源不断的传输、到达和在 buffer 等待。
一、Buffer概念:
在网络通信中,拿前端举例,客户端发送请求给服务器请求index.html,则服务器会以字符串的形式返回给客户端html文件,但是像mp3、flv、mp4这些媒体文件实际上是二进制数据文件,所以当客户端请求时,服务器必须分块以二进制的形式给客户端发送数据,传统的Array数据类型不足以储存这些数据,Buffer就是为了弥补Array而产生的。
Buffer就是缓冲区,用来存储数据的容器,操作和数组类似,js中对于数组的操作很多都可以使用,它的每个元素储存2位16进制的数据,一个元素就代表内存的一个字节(简化一下就是:buffer 能够与二进制数据流进行交互操作。)
Buffer不需要引入可以直接使用
捋一下:
- Buffer是在内存中开辟一段空间用来存储数据的
- 数据都是二进制的
二、Stream概念:
流(stream)在 Node.js 中是处理流数据的抽象接口(abstract interface)。 stream 模块提供了基础的 API 。使用这些 API 可以很容易地来构建实现流接口的对象。
流(stream)就是一系列从A点到B点移动的数据,完整点的说,就是当你有一个很大的数据需要传输、搬运时,你不需要等待所有数据都传输完成才开始下一步工作。
实际上,大型数据会被分割成小块(chunks)进行传输。所以,buffer 的原始定义中所说的(“streams of binary data… in the context of… file system”)意思就是说二进制数据在文件系统中的传输。比如,将 file1.txt 的文字存储到 file2.txt 中。
捋一下:
- Stream的三大原则:有源头、有终点、源头流向终点
- Stream就像老司机,将装着数据的Buffer开向终点
特性:流是可读的、可写的,或是可读写的。
4种流类型:
- Readable - 可读的流(fs.createReadStream())
- Writable -可写的流(fs.createWriteStream())
- Duplex - 可读写的流(net.Socket)
- Transform -在读写过程中可以修改和变换数据的 Duplex 流 (例如 zlib.createDeflate())
所有的 Stream 对象都是 EventEmitter 的实例。常用的事件有:
- data - 当有数据可读时触发
- end - 没有更多的数据可读时触发
- error - 在接收和写入过程中发生错误时触发
- finish - 所有数据已被写入到底层系统时触发