Stream接口
数据读写可以看作是事件模式(Event)的特例,不断发送的数据块好比一个个的事件。读数据是read
事件,写数据是write
事件,而数据块是事件附带的信息。Node 为这类情况提供了一个特殊接口Stream
。
概念
”数据流“(stream)是处理系统缓存的一种方式。操作系统采用数据块(chunk)的方式读取数据,每收到一次数据,就存入缓存。Node应用程序有两种缓存的处理方式,第一种是等到所有数据接收完毕,一次性从缓存读取,这就是传统的读取文件的方式;第二种是采用“数据流”的方式,收到一块数据,就读取一块,即在数据还没有接收完成时,就开始处理它。
解释两种方式:第一种方式先将数据全部读入内存,然后处理,优点是符合直觉,流程非常自然,缺点是如果遇到大文件,要花很长时间,才能进入数据处理的步骤。第二种方式每次只读入数据的一小块,像“流水”一样,每当系统读入了一小块数据,就会触发一个事件,发出“新数据块”的信号。应用程序只要监听这个事件,就能掌握数据读取的进展,做出相应处理,这样就提高了程序的性能。
var fs = require('fs'); fs .createReadStream('./data/customers.csv') .pipe(process.stdout);
上面代码中,fs.createReadStream
方法就是以”数据流“的方式读取文件,这可以在文件还没有读取完的情况下,就输出到标准输出。这显然对大文件的读取非常有利。
Unix操作系统从很早以前,就有“数据流”这个概念,它是不同进程之间传递数据的一种方式。管道命令(pipe)就起到在不同命令之间,连接数据流的作用。“数据流”相当于把较大的数据拆成很小的部分,一个命令只要部署了数据流接口,就可以把一个流的输出接到另一个流的输入。Node引入了这个概念,通过数据流接口为异步读写数据提供的统一接口,无论是硬盘数据、网络数据,还是内存数据,都可以采用这个接口读写。
数据流接口最大特点就是通过事件通信,具有readable
、writable
、drain
、data
、end
、close
等事件,既可以读取数据,也可以写入数据。读写数据时,每读入(或写入)一段数据,就会触发一次data
事件,全部读取(或写入)完毕,触发end
事件。如果发生错误,则触发error
事件。
一个对象只要部署了数据流接口,就可以从它读取数据,或者写入数据。Node内部很多涉及IO处理的对象,都部署了Stream接口,下面就是其中的一些。
- 文件读写
- HTTP 请求的读写
- TCP 连接
- 标准输入输出