nodeJS Stream 模块

流的四种类型

  • 可读流
  • 可写流
  • Duplex:双工流 net.socket 比如聊天系统,既可以发送消息也可以接收消息
  • transform:转换流 也算是双工流 如文件压缩 既可以读取数据也可以写入数据
    stream 对象都是EventEmiter的实例,拥有data,end,error等方法
const fs = require('fs');

// 创建一个可读流数据
const rs = fs.createReadStream("demo.txt"); 
// 创建一个可写流数据 
const ws = fs.createWriteStream("copy1.txt");
// 监听数据传输, 块 buffer 二进制
// 不停进行数据读取,触发data事件
// 可读流:两种模式,自动流动flowing模式 手动流动pushed stream.read();
rs.on("ready", ()=>{
  console.log('the file is open');
})
// flowing mode                                                                                                                                                                                                                                            
rs.on("data", chunk => {
  console.log(chunk);
  ws.write(chunk);
});
rs.on("error", error=>{
  console.log('error:'+ error);
});
rs.on("close", ()=>{
  console.log('the file is closed');;
});
rs.on("end", () => {
  ws.end();
});
transform stream 转换流

继承自双工流 要求用户自己实现一个transform方法,进行数据转换

const stream = require("stream");
const transform = stream.Transform({
  // 需要用户自己实现这个transform方法
  transform(chunk, encoding, cb) {
    // 大小写字母转换,push 到缓存区
    this.push(chunk.toString().toLowerCase());
    // 用户自己实现这个方法 需要进行一个回调
    cb();
  }
});
transform.write("HOLA MARISOL QUE TAL?");
console.log('transformed successfully! ',transform.read().toString());

pipe 管道 保证读写速度 方式数据丢失

// 通过pipe方法 就像是用一根管道来输送液体 不会出现数据丢失的问题
// pipe 只是可读流的方法 不要写反了
rs.pipe(ws);

读写的时候有一个缓存区,可以对缓存区的大小进行设置

// 设置一个缓冲区,大小默认16k,比如32k, 就会读取两次,每一次等缓存区满了之后再进行下一次
const rs = fs.createReadStream("data.txt",{
  encoding: 'utf8', // 显示为字符串 莫认为二进制
  highWaterMark: 6, // 单位byte 字节, 默认为16btye
})

链式流操作

类似于通过点点点的方式进行链式操作,是创建多个流进行操作的机制,常用于pipe操作

// 文件压缩
const fs = require('fs');
const zilb = require('zlib');

fs.createReadStream('data.txt')
.pipe(zilb.createGzip())
.pipe(fs.createWriteStream('data.txt.gz'))
console.log('finish');
const stream = require("stream");
const transform = stream.Transform({
  transform(chunk, encoding, cb) {
    // 大小写字母转换,push 缓存区
    this.push(chunk.toString().toLowerCase());
    cb();
  }
});
transform.write("HOLA MARISOL QUE TAL?");
console.log('transformed successfully! ',transform.read().toString());

按行读取的最佳方案 readLine

比如很多日志文件都是分行的,最好是一行一行进行读取

// 示例,计算 log.txt 中http://1234.com访问次数
const fs = require('fs');
const path = require('path');
const readLine = require('readline');

const fileName  = path.resolve(__dirname,"log.txt");
const readStream = fs.createReadStream(fileName);
const readL = readLine.createInterface({
  // 输入
  input: readStream
});
let count = 0;
readL.on('line', data => {
  console.log(data);
  if(data.indexOf('http://1234.com')>-1){
    count++;
  }
});
readL.on('close', () => {
  console.log("读取完成", count);
});

在 stream中默认使用buffer 二进制

在i/o(input/output)操作中,数据格式未知,字符串、音频、网络包, asc编码 utf8编码
二进制无论那种格式都认识,而且效率非常高

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 接触过 Node.js 的开发人员可能知道,流(Stream)这个概念比较难理解,也不太好处理。 用 Domini...
    1024译站阅读 5,371评论 0 1
  • Stream 是Node.js中最重要的组件和模式之一,在构建较复杂的系统时,通常将其拆解为功能独立的若干部分。这...
    ElineC阅读 3,240评论 0 1
  • 什么是流 流是一个在node中与流数据工作的抽象接口,stream模块提供了一个基本的API,使得比较容易创建一个...
    shawlp阅读 3,858评论 0 0
  • 流的基本概念及理解 流是一种数据传输手段,是有顺序的,有起点和终点,比如你要把数据从一个地方传到另外一个地方流非常...
    October_yang阅读 12,279评论 3 9
  • 流(stream),看一个人流不流逼,就看你对流的理解了 学习本无底,前进莫徬徨 今天跟大家分享的是node.js...
    Shinemax阅读 3,008评论 0 2