zhaobinglong / myBlog

https://zhaobinglong.github.io/myBlog/
MIT License
7 stars 0 forks source link

nodejs之stream流 #84

Open zhaobinglong opened 3 years ago

zhaobinglong commented 3 years ago

流原理

fs 本身提供了 readFile 和 writeFile,它们好用的代价就是性能有问题,会将内容一次全部载入内存。但是对于几 GB 的大文件,显然会有问题。

那么针对大文件的解决方案自然是:一点点读出来。这就需要用到 stream 了。以 readStream 为例

var http = require('http');
var fs = require('fs');

//  利用stream,读取data.txt文件到内存,然后返回
var server = http.createServer(function (req, res) {
    let stream = fs.createReadStream(__dirname + '/data.txt');//创造可读流
    stream.pipe(res);//将可读流写入response, pipe方法如同stream和response之间的一个管道,将data.txt文件一小段一小段地发送到客户端,减小了服务器的内存压力。
});
server.listen(8000);

四种流类型

Readable - 可读的流 (例如 fs.createReadStream()). Writable - 可写的流 (例如 fs.createWriteStream()). Duplex - 可读写的流 (例如 net.Socket). Transform - 在读写过程中可以修改和变换数据的 Duplex 流 (例如 zlib.createDeflate()

zhaobinglong commented 3 years ago

可读流实例

let fs = require('fs');
//通过创建一个可读流
let rs = fs.createReadStream('./1.txt',{
    flags:'r',//我们要对文件进行何种操作
    mode:0o666,//权限位
    encoding:'utf8',//不传默认为buffer,显示为字符串
    start:3,//从索引为3的位置开始读
    //这是我的见过唯一一个包括结束索引的
    end:8,//读到索引为8结束
    highWaterMark:3//缓冲区大小
});
rs.on('open',function () {
    console.log('文件打开');
});
rs.setEncoding('utf8');//显示为字符串
//希望流有一个暂停和恢复触发的机制
rs.on('data',function (data) {
    console.log(data);
    rs.pause();//暂停读取和发射data事件
    setTimeout(function(){
        rs.resume();//恢复读取并触发data事件
    },2000);
});
//如果读取文件出错了,会触发error事件
rs.on('error',function () {
    console.log("error");
});
//如果文件的内容读完了,会触发end事件
rs.on('end',function () {
    console.log('读完了');
});
rs.on('close',function () {
    console.log('文件关闭');
});

/**
文件打开
334
455
读完了
文件关闭
**/