阅读 107

NODE.JS stream

流的概念

  • 流是一组有序的 有起点和有终点的字节数据传输手段
  • 不关心文件的整体内容,只关注是否从文件中读到了数据,以及读到数据之后的处理
  • 流是一个抽象的接口 被node中的很多对象所实现 比如我们比较熟悉的HTTP服务器request和response对象都是流

可读流createReadStream

fs.createReadStream = function(path, options){
    return new ReadStream(path, options)
}
util.inherits(ReadStream, Readable)
复制代码

实现了stream.Readable接口的对象,将对象数据读取为流数据,为监听data事件后,开始发射数据

let rs = fs.creatReadStream(path, [optins])
// 创建可读流, path为读取文件的路径
rs,setEncoding('utf8') // 设置编码
rs.on('data', function(data){
    console.log(data)
    rs.pause() // 暂停触发data
    rs.resume() // 恢复触发流
})
// 监听data事件 流切换到流动模式 数据尽可能快的读出
rs.on('end', function(){
    console.log('读取完成')
})
// 监听end事件 在读取完之后触发
rs.on('error', function(err){
    console.log(err)
})
// 监听error事件
rs.on('open', function(err){
    console.log(err)
})
rs.on('close', function(err){
    console.log(err)
})
复制代码

可写流createWriteStream

实现了stream.Writeable接口的对象将流数据写入到对象中

fs.createWriteStream = function(path, options) {
  return new WriteStream(path, options)
};

util.inherits(WriteStream, Writable)
复制代码

下边实现一下


let ws = fs.createWriteStream(path, [options])
// 创建一个可写流
ws.write(chunk, [encoding],[callback])

// chunk为写入的数据buffer/string 

ws.end(chunk,[encoding],[callback])
// 表明接下来没有数据要被写入 Writable 通过传入可选的 chunk 和 encoding 参数,可以在关闭流之前再写入一段数据 如果传入了可选的 callback 函数,它将作为 'finish' 事件的回调函数
复制代码

drain方法

  • 当一个流不在drain的状态 对write()的调用会缓存数据块 并且会返回false 一旦所有缓存的数据都排空 drain就会被触发
let fs = require('fs');
let ws = fs.createWriteStream('./2.txt',{
  flags:'w',
  encoding:'utf8',
  highWaterMark:3
});
let i = 10;
function write(){
 let  flag = true;
 while(i&&flag){
      flag = ws.write("1");
      i--;
     console.log(flag);
 }
}
write();
ws.on('drain',()=>{
  console.log("drain");
  write();
});
复制代码

finish

如果调用了stream.end 方法 且缓冲区数据都已经都传给底层系统之后 finish就会触发

let writer = fs.createWriteStream('./2.txt');
for (let i = 0; i < 100; i++) {
  writer.write(`hello, ${i}!\n`);
}
writer.end('结束\n');
writer.on('finish', () => {
  console.error('所有的写入已经完成!');
});
复制代码

pipe

pipe的原理

let fs = require('fs')
let ws = fs.createWriteStream('./2.txt')
let rs = fs.createReadStream('./1.txt')
rs.on('data', function (data) {
    let flag = ws.write(data);
    if(!flag)
    rs.pause()
})

ws.on('drain', function () {
    rs.resume()
})
rs.on('end', function () {
    ws.end()
})
复制代码

pipe的用法

readStream.pipe(writeStream);
let from = fs.createReadStream('./1.txt');
let to = fs.createWriteStream('./2.txt');
from.pipe(to);
复制代码

将数据的滞留量限制到一个可接受的水平,以使得不同速度的来源和目标不会淹没可用内存。

实现以下pipe的用法

let fs = require('fs');
let ReadStream = require('./ReadStream');
let rs = ReadStream('./1.txt', {
    flags: 'r',
    encoding: 'utf8',
    highWaterMark: 3
});
let FileWriteStream = require('./WriteStream');
let ws = FileWriteStream('./2.txt',{
    flags:'w',
    encoding:'utf8',
    highWaterMark:3
});
rs.pipe(ws);
复制代码

option的解释

  • flags打开文件要做的操作,默认为'r'
  • encoding默认为null
  • start开始读取的索引位置
  • end结束读取的索引位置(包括结束位置)
  • highWaterMark读取缓存区默认的大小64kb
文章分类
前端