什么是Stream流?
stream是水流,但默认没有水(数据),如果要有水(数据),就使用stream.write
有水(数据)。
每次写的一个小数据,就叫做chunk(块),产生数据的一段叫做source(源头),得到的数据的一段叫做sink(水池)。如图
例子代码:
//引用node的fs模块
const fs = require('fs');
//对big_file.txt创建stream
const stream = fs.createWriteStream('./big_file.txt');
for(let i = 0; i < 10000; i++) {
//对该文件进行10000次的写入
stream.write(`第${i}行正在输入,输入了这些很多很多的内容`)
}
//写完后要关闭stream
stream.end();
配合HTTP使用Stream
例子如下:
const fs = require('fs');
const http = require('http')
const server = http.createServer();
server.on('request', (request, response) => {
fs.readFile('./big_file.txt', (error, data) => {
if(err) throw err;
response.end(data);
})
})
server.listen(8888)
这样写的话,用户访问8888端口的时候,服务端就会很快的占用100多M的内存,一个用户还好,如果多个用户,就会撑爆服务器,所以需要进行优化。
stream.pipe
的使用
上一个例子说明了占用内存过大的情况,可以使用pipe来解决:
const fs = require('fs'); //引用node的fs模块
const http = require('http')
const server = http.createServer();
server.on('request', (request, response) => {
// fs.readFile('./big_file.txt', (error, data) => {
// if(error) throw error;
// response.end(data);
// })
const stream = fs.createReadStream('./big_file.txt');
stream.pipe(response)
})
server.listen(8888)
该示例代码,相比上一个例子,占用内存最高不过30mb,会一点一点的传输到页面,而不是一股恼的全部传送。
pipe解释:
中文俗称“管道”,可以连接两个流,例如stream1流末尾连接到stream2流的开端,这样1号的数据就会流向2号的去。具体用法是这样的:stream1.pipe(stream2)
。
当然,也可以一直连接下去:stream1.pipe(stream2).pipe(stream3)
,
等价于:stream1.pipe(stream2)
stream2.pipe(stream3)
可以不用pipe,用事件来实现管道:
//stream1 一有数据的那一刻,就塞给stream2
stream1.on('data', (chunk) => {
stream2.write(chunk)
})
stream1.on('end', () => {
stream2.end()
})