Node.js数据流(Stream接口)

1 概述

数据读写可以看作是事件模式(Event)的特例,不断发送的数据块好比一个个的事件。读数据是read事件,写数据是write事件,而数据块是事件附带的信息。Node 为这类情况提供了一个特殊接口Stream。

“数据流”(stream)是处理系统缓存的一种方式。操作系统采用数据块(chunk)的方式读取数据,每收到一次数据,就存入缓存。Node应用程序有两种缓存的处理方式:

1、所有数据接收完毕后,一次性从缓存读取(传统方式)。优点:符合直觉,流程非常自然;缺点:如果遇到大文件,要花很长时间,才能进入数据处理的步骤。

2、采用“数据流”的方式,收到一块数据,就读取一块。优点:提高了程序的性能。

2 什么是流

流是可以从一个源读取或写入数据到连续的目标对象。在Node.js,有四种类型的数据流:

  • Readable:用于读操作。
  • Writable:用在写操作。
  • Duplex:用于读取和写入操作。
  • Transform:输出基于输入的地方进行计算的一种双相流。

每种流都是事件触发器,当某个流被调用时,就会触发,抛出一个事件,一些常用的事件是:

事件说明
data表示流中有数据可以读取
end表示流中没有数据可以读取
error读写数据错误时触发
finish数据刷新到底层系统时触发

3 从流中读取

fs模块的createReadStream方法,就可以创建一个读取数据的数据流。

示例代码:

const fs = require("fs");
let data = "";

//建立一个输入流
let readerStream = fs.createReadStream("./out.txt");
//设置字符集
readerStream.setEncoding("UTF8");
//绑定流事件-->data,end,and error
readerStream.on("data", function (chunk) {
    data += chunk;
})
readerStream.on("end", function () {
    console.log(data);
})
readerStream.on("error", function (err) {
    console.log(err.stack);
})
console.log("程序结束");

在这里插入图片描述
上述程序将out.txt中的内容读出来了。

4 写入流

fs模块的createWriteStream方法,就可以创建一个写数据的数据流。

示例代码:

var fs = require("fs");
var data = "橘猫吃不胖";

//创建一个写入流
var writerStream = fs.createWriteStream('./out.txt');
//设置写入数据的字符集
writerStream.write(data, 'UTF8');
//文件结束退出
writerStream.end();
//绑定流事件 --> finish,and error
writerStream.on("finish", function () {
    console.log("写入结束");
});
writerStream.on("error", function (err) {
    console.log(err.stack);
});
console.log("程序结束");

在这里插入图片描述
本程序将out.txt文件中的内容更新为了:橘猫吃不胖,原本的古诗被删除了。

5 管道流

管道是供一个流的输出作为输入到另一个流的机制。它通常被用于从一个流中获取数据,并通过该流输出到另一个流。

示例:一个管道从一个文件中读取和写入到另一个文件

var fs = require("fs");
//创建一个可读流
var readerStream = fs.createReadStream("./out.txt");
//创建一个可写流
var writerStream = fs.createWriteStream("./output.txt");
//通过管道进行读和写操作
//读取out.txt,并将数据写入output.txt
readerStream.pipe(writerStream);
console.log("程序结束");

在这里插入图片描述
原本的out.txt文件中含有内容:橘猫吃不胖,运行本程序后,output.txt文件中也包含该内容(原本有output.txt文件并且该文件是空文件)。

4 链式流

链式是一个机制,一个流的输出连接到另一个流,并创建一个链多流操作。它通常用于管道的操作。

示例:使用管道和链接先压缩文件,然后解压缩
zlib模块:用于对文件的压缩和解压缩

示例代码:压缩文件

const fs = require("fs");
const zlib = require("zlib");

//创建一个读数据的流
let readerStream = fs.createReadStream("./out.txt").pipe(zlib.createGzip()).pipe(fs.createWriteStream("./out.zip"));

readerStream.on("error", function (err) {
    console.log(err.stack);
})
console.log("-----程序结束-----");

在这里插入图片描述
在文件夹中出现了一个压缩包:out.zip

示例代码:解压文件

const fs = require("fs");
const zlib = require("zlib");

fs.createReadStream("./test.zip").pipe(zlib.createGunzip()).pipe(fs.createWriteStream("./output.txt"))

文件夹中的test.zip文件被解压成了output.txt文件。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值