2

每日灵魂一问-对Node 中的 Stream 的理解?应用场景?

 2 years ago
source link: https://segmentfault.com/a/1190000040140182
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Stream


数据传输手段,是有顺序的
它不像传统的程序那样一次将一个文件读入内存
而是逐块读取数据

比如:
1.看视频
视频资源不是一次性返回的;而是一点点从服务端流动到本地播放器
一边流动一边播放;这就是用的流

2.读大文件
如果用,创建读取流createReadStream 通过pipe链接
可以一边读取一边返回 减轻了服务器的压力;
如果直接用readFile;会将整个文件一次性返回,内存和网络可能会吃不消

可写流:可写入数据的流。例如 fs.createWriteStream() 可以使用流将数据写入文件

可读流:可读取数据的流。例如fs.createReadStream() 可以从文件读取内容

双工流:既可读又可写的流。例如 net.Socket

转换流:可以在数据写入和读取时修改或转换数据的流。例如,在文件压缩操作中,可以向文件写入压缩数据,并从文件中读取解压数据

适用于IO操作:http请求&文件操作

具体场景有:

  1. get请求返回文件给客户端
  2. 一些打包工具的底层操作

1.get请求返回文件给客户端

使用stream流返回文件,res也是一个stream对象,通过pipe管道将文件数据返回

const server = http.createServer(function (req, res) {
    const method = req.method; // 获取请求方法
    if (method === 'GET') { // get 请求
        const fileName = path.resolve(__dirname, 'data.txt');
        let stream = fs.createReadStream(fileName);
        stream.pipe(res); // 将 res 作为 stream 的 dest
    }
});
server.listen(8000);

2.文件操作

创建一个可读数据流readStream,一个可写数据流writeStream,通过pipe管道把数据流转过去

const fs = require('fs')
const path = require('path')

// 两个文件名
const fileName1 = path.resolve(__dirname, 'data.txt')
const fileName2 = path.resolve(__dirname, 'data-bak.txt')
// 读取文件的 stream 对象
const readStream = fs.createReadStream(fileName1)
// 写入文件的 stream 对象
const writeStream = fs.createWriteStream(fileName2)
// 通过 pipe执行拷贝,数据流转
readStream.pipe(writeStream)
// 数据读取完成监听,即拷贝完成
readStream.on('end', function () {
    console.log('拷贝完成')
})

3.一些打包工具的底层操作

目前一些比较火的前端打包构建工具,都是通过node.js编写的,打包和构建的过程肯定是文件频繁操作的过程,离不开stream,如gulp


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK