Node.js入门笔记(7):Stream

128 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第9天,点击查看活动详情

Stream模块也是Node中比较常用的模块,通常是提供操作流式数据的支持。在Node中使用该模块,需要引入

var stream = require('stream')

stream在Node中通常有四种类型

  • Readable:可读流;
  • Wirteble:可写流;
  • Duplex:可读可写;
  • Transform:操作写入的数据,然后读取结果;

readable stream的例子

var fs = require('fs');
var readStrem = fs.createReadStream("./readLine/readLine.txt")
readStrem.on("data",function(data){
    console.log(data);
})
readStrem.on("close",function(){
    console.log('closed');
})

readStrem.on("err",function(){
    console.log('err');
})

通过readstream可以读取到文件的流数据 image.png

创建一个静态文件服务器

开启一个服务,如果访问的是根目录,那么输出根目所有的文件名

如果访问的是某个文件,则读取文件的内容,然后写入到node1.txt文件中

访问localhost:3000/node.txt,那么路径path是./node.txt

fs.createReadStream(path)读取文件node.txt的文件流,读取完成之后,通过writeStream写入到node1.txt中

而pipe提供了一个管道流数据的传输,就是在读取文件的同时也可以写入文件,将node读取的内容写入到node1中

var stream = require('stream');
var http = require('http');
var fs  = require('fs');
var server = http.createServer(function(req,res){
    if(req.url=='/'){
        console.log(666);
        var fileList = fs.readdirSync("./")
        res.writeHead(200,{"Content-type":"text/plain"})
        res.end(fileList.toString())
    }else{
        var path = "."+req.url
        console.log(path);
        var readStream = fs.createReadStream(path)
        var writeStream = fs.createWriteStream('./node1.txt')
        readStream.pipe(writeStream)
    }
})

server.listen(3000)

已经将node.txt中的内容读取到node1.txt中 image.png

如下面的图片所示,我们把文件比作装水的桶,而水就是文件里的内容,我们用一根管子(pipe)连接两个桶使得水从一个桶流入另一个桶,这样就慢慢的实现了大文件的复制过程。如果可读流的文件较大,读取速度大于写入速度,Node会在内存中缓存这些数据。

可以想象一下这个管道是是弹性的,可以根据管道中的数据变大,但是变大到一定程度也会到达限度,缓冲区的大小达到阈值后wirte会返回false,可读流也进入暂停状态

image.png

readLine模块

readLine提供了按行读取Stream中数据的功能,该模块会配合stream来使用,但是我们由于可以自定义自己的stream,readLine的使用可能会较少,下面看一个例子

var readLine = require('readline');
var fs = require('fs');
var rl = readLine.createInterface({
    input:fs.createReadStream("./readLine/readLine.txt")
})
rl.on("line",function(data){
    console.log(data);
})

rl.on("close",function(){
    console.log('closed');
})

image.png

先看下readLine中的数据格式,这里是有三行字母所以是按行读取的话,就应该分三次输出三行的数据

image.png