美文网首页
Stream - 流

Stream - 流

作者: littleyu | 来源:发表于2020-06-29 12:49 被阅读0次

stream 释义

  • stream 是水流,但默认没有水
  • stream.write 可以让水流中有水(数据)
  • 每次写的小数据叫做 chunk (块)
  • 产生数据的一段叫做 source (源头)
  • 得到数据的一段叫做 sink (水池)
实用栗子

用 stream 和不用 stream 传输大文件时,node 占用内存区别很大
用 stream 时,读一个 150m 的文件,基本不会高于 30m
但是不用 stream,内存占用 100m+,要知道分配给nodeJs的内存有限,所以用 stream 就可以一点一点慢慢传

管道 释义

  • 两个流可以用一个管道相连
  • stream1 的末尾连接上 stream2 的开端
  • 只要 stream1 有数据,就会流到 stream2

pipe 也可以通过事件实现

// stream1 有数据就塞给 stream2
stream1.on('data', chunk => {
  stream2.write(chunk)
})
// stream1 停了,就停掉 stream2
stream1.on('end', () => {
  stream2.end()
})

Stream 对象的原型链

栗子

  • 自身属性(由fs.Readable.prototype 构造)
  • 原型:stream.Readable.peototype
  • 二级原型: stream.Stream.prototype
  • 三级原型:events.EventEmitter.prototype
  • 四级原型:Object.prototype
  • Stream 对象都继承了 EventEmitter

支持的事件和方法

Stream 分类

  • Readable 可读
  • Writeable 可写
  • Duplex 可读可写(双向)(读写一般不交叉)
  • Transform 可读可写(变化)(自己写,自己读,webpack常用,比如把 scss 转换成 css,es6 编译成 es5)

手动实现一个 Readable 的流

const { Readable } = require('stream')

// 先推再读
// const inStream = new Readable()

// inStream.push('zch')
// inStream.push('233333333333333333')
// inStream.push(null) // no more data

// // inStream.pipe(process.stdout)
// // 等价于
// inStream.on('data', chunk => {
//   console.log('push')
//   console.log(chunk.toString())
// })


// 等读了再推
const inStream = new Readable({
  read(size) {
    const char = String.fromCharCode(this.charCode++)
    console.log('push\n')
    this.push(char)
    if (this.charCode > 90) {
      this.push(null)
    }
  }
})

inStream.charCode = 65

inStream.pipe(process.stdout)

手动实现一个 writable 的流

const { Writable } = require('stream')

const outStream = new Writable({
  write(chunk, encoding, callback) {
    console.log(chunk.toString())
    callback()
  }
})

process.stdin.pipe(outStream)

手动实现一个 duplex 的流

// 只需要把 writable 和 readable 结合起来,同事实现 read 和 write 方法即可

手动实现一个 transform 的流

const { Transform } = require('stream')
const upperTransform = new Transform({
  transform (chunk, encoding, callback) {
    this.push(chunk.toString().toUpperCase())
    callback()
  }
})

process.stdin.pipe(upperTransform).pipe(process.stdout)
transform 的流的栗子(实现gzip):
const fs = require('fs')
const zlib = require('zlib')
const file = process.argv[2]

fs.createReadStream(file)
  .pipe(zlib.createGzip())
  .pipe(fs.createWriteStream(file + '.gz'))
升级(加点进度条)
const fs = require('fs')
const zlib = require('zlib')
const file = process.argv[2]

fs.createReadStream(file)
  .pipe(zlib.createGzip())
  .on('data', () => console.log('.'))
  .pipe(fs.createWriteStream(file + '.gz'))
  .on('finish', () => console.log('Done'))
再次升级(升级为一个 transform 方法)
const fs = require('fs')
const zlib = require('zlib')
const file = process.argv[2]

const { Transform } = require('stream')
const transform = new Transform({
  transform (chunk, encoding, callback) {
    console.log('.')
    callback(null, chunk)
  }
})


fs.createReadStream(file)
  .pipe(zlib.createGzip())
  .pipe(transform) // 这里可以做进度条,webpack 就是这样的原理,vue-loader => scss-loader => css-loader => style-loader
  .pipe(fs.createWriteStream(file + '.gz'))
  .on('finish', () => console.log('Done'))
再次升级(我们还可以加密内容)
const fs = require('fs')
const zlib = require('zlib')
const file = process.argv[2]
const crypto = require('crypto')

const { Transform } = require('stream')
const transform = new Transform({
  transform (chunk, encoding, callback) {
    console.log('.')
    callback(null, chunk)
  }
})


fs.createReadStream(file)
  .pipe(crypto.createCipher('aes192', '123456'))
  .pipe(zlib.createGzip())
  .pipe(transform) // 这里可以做进度条,webpack 就是这样的原理,vue-loader => scss-loader => css-loader => style-loader
  .pipe(fs.createWriteStream(file + '.gz'))
  .on('finish', () => console.log('Done'))

Stream 用途广泛

参考
文档
面试题

相关文章

  • JDK8新特性之Stream流

    是什么是Stream流 java.util.stream.Stream Stream流和传统的IO流,它们都叫流,...

  • 2020-07-04【Stream流】

    体验Stream流 Stream流的生成方式 Stream流的常见中间操作 Stream流的常见终结操作 Stre...

  • JavaStream流基础学习

    Stream流 Straem流使用 使用Sream流: 一行搞定 1.2 Stream流生成方式 Stream流的...

  • 2019-02-02——Java8 Stream

    Stream分为两种: 串行流——stream() 并行流——parallelStream() Stream的特性...

  • Stream流

    流式思想 Stream流的简单尝试 传统for循环遍历的方法 Steam流的方式 获取stream流 stream...

  • Stream流

    一、创建流 Arrays.stream Stream.of Collection.stream Stream.it...

  • 13.Stream流、方法引用

    主要内容 Stream流 方法引用 第一章 Stream流 说到Stream便容易想到I/O Stream,而实际...

  • Stream流

    体验Stream Stream流生产方式生成流list.stream()中间操作filter()终结操作forEa...

  • Stream操作

    1、创建Stream流 2、stream和parallelStream的简单区别 stream是顺序流,由主线程按...

  • 2020-07-20Stream流

    Stream流的生成方式 stream流的使用 生成流通过数据源(集合,数组等)生成流list.stream() ...

网友评论

      本文标题:Stream - 流

      本文链接:https://www.haomeiwen.com/subject/hvlctktx.html