背景
- 我听说nodejs的流是常见的面试考点,这次详细总结下。
读流
一、读流的用法
- 这个fs.createReadStream是基于原生的require(‘stream’)
//a用于文件追加,不存在则创建
//w+ 文件读取和写入,不存在创建,存在就截断
const fs = require('fs')
let rs = fs.createReadStream('./sss.txt',{//可读流对象
flags:'r',
//encoding:null,//表示二进制 默认
mode:0o666,//8进制,d rwx r-x r-x 第一个d代表文件夹,后三位代表自己,中间代表组成员,最后代表访客。
//2读4写1执行。2+4就是6代表能写能读 777就是最大权限。也可以写十进制438
autoClose:true,//是否自动关闭
start:0,
end:5,//包前包后
highWaterMark:2
})
//内部发布订阅模式
//默认是暂停模式
//监听data会改为流动模式
let arr =[]
rs.on('open',function (fd) {
console.log('open',fd);
})
rs.on('data',function (data) {//读到的是buffer
arr.push(data)
})//固定的,内部emit的data
rs.on('end',function () {
console.log(Buffer.concat(arr).toString());//转成读到的文字
})
rs.on('close',function () {
console.log('close');
})
- 另外
rs.pause()
可以把流动模式改为暂停模式,恢复使用rs.resume()
二、写流的用法
const fs = require('fs')
let ws = fs.createWriteStream('./jj.txt',{
flags:'w',
highWaterMark:5,//代表期望占用多少内存
autoClose:true,
start:0,
end:0,
mode:0o666,
encoding:'utf8'//默认
})
let index =0
function write() {
let flag=true
while(index<10&&flag){
flag=ws.write(index++ + '')//只能字符串或者buffer
}//flag是写入大于highwatermark就会false
if(index===10){
ws.end('xx')//end是加最后语句并且close文件,后面就不能写了。
}
}
write()
ws.on('drain',function () {//写入内容超过highwatermark会触发
console.log('drain');//触发drain就不会继续写了
write()//在drain里可以继续完成任务
})
三、拷贝
- 实际拷贝封装好了,不需要通过手写读流+写流实现。
const fs = require('fs')
rs = fs.createReadStream('./sss.txt',{
highWaterMark:4
})
ws = fs.createWriteStream('./jj.txt',{
highWaterMark:1
})
rs.pipe(ws)
- 也可以通过读流和写流实现拷贝:
const fs = require('fs')
rs = fs.createReadStream('./sss.txt',{
highWaterMark:4//读的多,写的少
})
ws = fs.createWriteStream('./jj.txt',{
highWaterMark:1
})
rs.on('data',function (chunk) {
let flag=ws.write(chunk)
if(!flag){
//说明满了
rs.pause()//暂停读取
}
})
ws.on('drain',function(){
rs.resume()//写完继续读,重新触发data
})