Node.js中 什么是Piping
Piping 在NodeJS中是将一个流的字节数据发送到另一个流的过程。
什么是流?
在NodeJS中,流是一系列字节。当程序处理一些数据时,它需要将所有数据读入内存,然后处理数据并将数据写回某个位置。然而,当要处理大量数据时,这种方法会失败。为了解决这个问题,使用流算法来处理数据,其中数据不是一次性全部读入,而是“流”进程序,经过处理后,“流”出程序。在这里,数据以小块进行处理,整个数据不是一次性全部呈现在内存中。数据流可以与水流在河中流动的示例进行比较,在一段时间内通过河流流动来运输大量的水。流算法更节省内存并且更快。你可以阅读这篇文章来获得有关流的详细指南。
什么是piping?
在NodeJS中,当我们需要将来自源流的一些数据写入另一个流时,piping非常有用。在这种情况下,我们可以使用NodeJS提供的piping算法,而不是编写自己的读取和写入逻辑。我们基本上将读取流和写入流连接在一起。这可以与使用管道连接两个水体以转移水进行比较。
让我们以一个关于piping的示例为例,假设你想编写一个服务器来提供一些文件。在这种情况下,你将需要编写处理文件的读取操作的代码,并编写将数据写入网络套接字的代码。但是借助NodeJS提供的piping功能,您可以轻松将文件流连接到网络套接字流以发送数据。NodeJS中提供了一个pipe()函数来处理这个操作,它接受一个流对象并接受一个流对象。
pipe函数可用于将输入流连接到输出流,或者可以与一系列流组合在一起以创建一个复杂的管道来执行某个任务。
请确保您的计算机上安装了NodeJS。如果没有,请从此处下载并安装。此项目中使用的所有模块都已默认包含在NodeJS中。
方法1: 使用pipe()连接读取流和写入流
项目结构: 我们的项目结构如下:
- index.js: 包含代码的主文件。
- input.txt: 从中读取数据的文件。
- output.txt: 写入数据的文件。
以下模块在这个方法中是必需的:
- fs: 文件流模块,用于创建和与文件流进行交互
步骤1: 创建一个名为input.txt的文件,并将下面的文本粘贴到其中。创建一个名为output.txt的文件,并保持为空。
GeeksForGeeks is awesome.
步骤2: 创建一个名为index.js的文件,并将以下代码粘贴到其中。
const fs = require("fs");
const fs = require("fs");
let rs = fs.createReadStream("./input.txt");
let ws = fs.createWriteStream("./output.txt");
function callback(msg) {
console.log(msg);
}
// pipeReadToWrite() accepts two streams a
// readStream and s writeStream and a callback function.
function pipeReadToWrite(readStream, writeStream, callback) {
// handles any error occurred in the stream
function handleError(err) {
// close the streams and call callback
readStream.close();
writeStream.close();
callback(err);
}
readStream
.on("error", handleError)
.pipe(writeStream)
.on("error", handleError)
.on("finish", callback);
}
pipeReadToWrite(rs, ws, callback);
let rs = fs.createReadStream("./input.txt");
let ws = fs.createWriteStream("./output.txt");
function callback(msg) {
console.log(msg);
}
// pipeReadToWrite() accepts two streams a
// readStream and s writeStream and a callback function.
function pipeReadToWrite(readStream, writeStream, callback) {
// handles any error occurred in the stream
function handleError(err) {
// close the streams and call callback
readStream.close();
writeStream.close();
callback(err);
}
readStream
.on("error", handleError)
.pipe(writeStream)
.on("error", handleError)
.on("finish", callback);
}
pipeReadToWrite(rs,ws,callback);
代码解释:
- 导入 fs (文件流) 模块,用于创建和操作文件流。创建一个读取流并将其连接到 input.txt,创建一个写入流并将其连接到 output.txt
- pipeReadToWrite() 函数接受一个读取流和一个写入流。
- handleError() 是一个处理读取或写入流中出现的任何错误的回调函数。
- 使用所需的参数执行 pipeReadToWrite() 函数。
步骤3: 通过在命令行中编写命令执行 index.js 文件
node index.js
输出: 打开output.txt文件,你将看到以下输出显示在其中。
GeeksForGeeks is awesome.
方法2: 连接超过两个流以创建复杂的工作流。
项目结构: 我们的项目结构将是:
- index.js: 包含代码的主要文件。
- input.txt: 要压缩的文件。
在这个示例中,我们连接多个流来压缩一个文件。
在这种方法中需要以下模块:
- fs: 文件流模块,用于创建和操作文件流。
- zlib: 提供了压缩文件的各种方法。
步骤1: 创建一个名为input.txt的文件,并将以下文本粘贴到其中。创建一个名为output.txt的文件并保持为空。
GeeksForGeeks is awesome.
步骤2: 创建一个名为index.js的文件,并将以下代码粘贴进去。
const fs = require("fs");
const zlib = require("zlib");
// gzip() function accepts a filename
// to be compressed and a callback function
function gzip(filename, callback) {
// Create the streams
let source = fs.createReadStream(filename);
let destination = fs.createWriteStream(filename + ".gz");
let gzipper = zlib.createGzip();
// Set up the pipeline
source
.on("error", callback)
.pipe(gzipper)
.pipe(destination)
.on("error", callback)
.on("finish", callback);
}
gzip("./input.txt", (msg) => {
console.log(msg);
});
代码解释:
- 包含所有所需的模块
- gzip() 函数接受一个文件路径和一个回调函数。它压缩指定路径中的文件,并在成功压缩文件后执行回调函数。
- 执行 gzip() 函数。
步骤3: 执行 index.js 文件。打开命令行并执行下面给出的命令:
node index.js
输出: 你会看到一个名为input.txt.gz的新文件被创建。这是input.txt的压缩版本。