DAY19: Stream pipe()做起来!!

今天要接着DAY:18浅谈Stream的概念,实作一些例子来解说。
在这篇的概念中有提到一个例子:文件的读取,若是按照原来的方式的话...

var http=require("http");
var fs=require("fs");
var server=http.createServer((req,res)=>
{
    fs.readFile("./Heartbeat.txt",(err,data)=>
{
        res.end(data);
    }); 
});
server.listen(3000);

当文件内容很大时,就会消耗不少服务器的记忆体,使用者等待的时间就会因此变长
而HTTP中的requestresponse都是属於"流"的物流件,
request属於可读流response属於可写流
因此将上面的例子改写成这样:

//ReadStream
var http=require("http");
var fs=require("fs");
var readstream=require("stream");
var server=http.createServer((req,res)=>
{       
       readStream=fs.createReadStream("./Heartbeat.txt");             
       readStream.pipe(res);//将可读流写入response    
});
server.listen(3000);

Stream就会利用缓冲区来储存被切割的数据来给程序读取文件,
如此一来,文件内容大时,就不用担心服务器的记忆体。
pipe()会自动的调用dataend事件,也就相当於:

var buf=[];
req.on("data",(chunck)=>
{
    buf.push(chunck);
});
req.on("end",()=>
{
    buf=Buffer.concat(buf).toString();
})

另外可以使用pipe的特性将流与流之间串连起来,达到好的效用!
像是使用pipe()复制文件就相当方便!
只要将一个文件设为可读流(readable),而把要复制过去的文件设为可写流,接着再透过pipe来完成,
其实就像是复制贴上一样。
首先准备两份文件:
第一份名为butterfly.txt (摘取自蔡依林-花蝴蝶),内容为以下:

https://ithelp.ithome.com.tw/upload/images/20211001/2014024451v7hoIjjz.png

第二份名为heartbeat.txt (摘取自BTS-Heartbeat),内容为以下:
https://ithelp.ithome.com.tw/upload/images/20211001/20140244oAKMXFvUIR.png

接下来我想将butterfly.txt的内容复制到heartbeat.txt这个档案。

//使用pipe()复制文件
var stream=require("stream");
****const fs=require("fs");
let butterfly=fs.createReadStream("./butterfly.txt");
let heartbeat=fs.createWriteStream("./heartbeat.txt");

butterfly.pipe(heartbeat);

首先导入stream模块与fs模块,
设定butterfly.txt为可读流,heartbeat.txt设为可写流。
执行结果:

https://ithelp.ithome.com.tw/upload/images/20211001/20140244kQbGD8EwvM.png

是不是觉得哪里怪怪的,怎麽没有执行结果…,
我也困惑了一下,但是其实执行结果已经结束了,
接着打开 heartbeat.txt 会发现里面的内容变成了 butterfly.txt 的内容。

https://ithelp.ithome.com.tw/upload/images/20211001/20140244E38UNkuDcb.png

也可以来个混搭,设定第三份文件名为 変わらないもの.txt ,内容为:

https://ithelp.ithome.com.tw/upload/images/20211001/20140244bZNVjnwXgp.png

//使用pipe()复制文件
var stream=require("stream");
const fs=require("fs");
let butterfly=fs.createReadStream("./butterfly.txt");
let heartbeat=fs.createWriteStream("./heartbeat.txt");
let neverchange=fs.createReadStream("./変わらないもの.txt");

butterfly.pipe(heartbeat);
neverchange.pipe(heartbeat);

変わらないもの.txt设为可读流。
执行结果:

https://ithelp.ithome.com.tw/upload/images/20211001/20140244s0VQm4Q1l8.png

https://ithelp.ithome.com.tw/upload/images/20211001/20140244g6og4xPVpV.png

https://ithelp.ithome.com.tw/upload/images/20211001/20140244FxtecTfFL3.png

可以看到,两个设为可读流的档案内容依然不变,
但是设为可写流的heartbeat.txt出现了两个可读流的内容!!

总结:

今天的重点就到这边,其实感觉要交代的东西还很多,但每研读完一篇就已经消耗了很多脑力…,
我认为在Stream中最重要的就是可写流可读流pipe()的运用。

另外,附上两张很可爱的动图,有便於直接理解pipe()的工作。
若不使用Stream(劳动仔...):

使用Stream(动感光波!!!):

动图来源:
https://www.cnblogs.com/vajoy/p/6349817.html


<<:  Day-20 堆叠(Stack)

>>:  Day18:亚季军

【Day23】[演算法]-插入排序法Insertion Sort

插入排序法(Insertion Sort),原理是逐一将原始资料加入已排序好资料中,并逐一与已排序好...

【Day 13】Array - Practice 1

题目 本题将给定一个正整数,请将其看作四位数字(亦即四位数以下则前面补 0),并找出将数字重新排序後...

Day 28 - Vue 与 HTTP请求 (3)

不过我们在前端与後端进行资料交换时,极有可能会遇到跨域问题。 何谓跨域问题呢? CORS(Cross...

【程序】给 23 - 28 岁的你的一封信 转生成恶役菜鸟工程师避免 Bad End 的 30 件事 - 29

来到了铁人赛的29天,扣除掉最後一集的心得,今天算是最後一个主题。 今天的影片和以往不太一样,我事...

Day14【Web】网路攻击:域名劫持

域名劫持又称作域名污染 英文有多种称呼方式: DNS hijacking DNS poisoning...