nodejs笔记4(steam)
流(stream)在 Node.js 中是处理流数据的抽象接口(abstract interface)。 stream 模块提供了基础的 API 。使用这些 API 可以很容易地来构建实现流接口的对象。从程序角度而言流是有方向的数据,简单的说 流 就是数据的加工操作与传递。
nodejs中关于 流 的操作都封装的 stream 模块中。
Node.js,Stream 有四种流类型:
Readable - 可读操作。
Writable - 可写操作。
Duplex - 可读可写操作.
Transform - 操作被写入数据,然后读出结果。
所有的 Stream 对象都是 EventEmitter 的实例。常用的事件有:
data - 当有数据可读时触发。
end - 没有更多的数据可读时触发。
error - 在接收和写入过程中发生错误时触发。
finish - 所有数据已被写入到底层系统时触发。
1.复制文件数据
fs接口:用于与文件系统进行交互,所有文件的系统操作都有同步和异步两种方式。
fs.createReadStream(path[, options])
和readFiles
的区别:
createReadStream
是给你一个ReadableStream
,你可以听它的'data',一点一点儿处理文件,用过的部分会被GC,所以占内存少。
readFile是把整个文件全部读到内存里。
const fs = require('fs');//文件系统模块
// 创建可读流
const rs = fs.createReadStream('hello.txt');
//创建可写操作流程
const ws = fs.createWriteStream('./result/result.txt');
将rs的内容结果复制进ws下的文件内
rs.pipe(ws);
有个值得注意地方:数据必须是从上游 pipe 到下游,也就是从一个 readable 流 pipe 到 writable 流。
2.为什么应该使用 Stream
有个用户需要在线看视频的场景,假定我们通过 HTTP 请求返回给用户电影内容,那么代码可能写成这样
const http = require('http');
const fs = require('fs');
http.createServer((req, res) => {
fs.readFile(moviePath, (err, data) => {
res.end(data);
});
}).listen(8080);
http.createServer([requestListener])
由于该方法属于http模块,使用前需要引入http模块(var http= require(“http”) )。
该函数用来创建一个HTTP服务器,并将 requestListener 作为 request 事件的监听函数
以上的代码会造成2个问题
1.电影文件需要读完之后才能返回给客户,等待时间超长
2.电影文件需要一次放入内存中,相似动作多了,内存吃不消
用流可以讲电影文件一点点的放入内存中,然后一点点的返回给客户(利用了 HTTP 协议的 Transfer-Encoding: chunked 分段传输特性),用户体验得到优化,同时对内存的开销明显下降
const http = require('http');
const fs = require('fs');
http.createServer((req, res) => {
fs.createReadStream(moviePath).pipe(res);
}).listen(8080);