Node.js Streams 怎么用?

文章导读
Previous Quiz Next 什么是 Streams? Stream 是一组数据。然而,与 array 或 string 不同,stream 对象中的所有数据不会一次性全部存储在内存中。相反,每次从 stream 中读取一个数据块到内存中。这使得 streams 更
📋 目录
  1. A 什么是 Streams?
  2. B 流类型
A A

Node.js - Streams



Previous
Quiz
Next

什么是 Streams?

Stream 是一组数据。然而,与 array 或 string 不同,stream 对象中的所有数据不会一次性全部存储在内存中。相反,每次从 stream 中读取一个数据块到内存中。这使得 streams 更加高效。Node.js 应用最适合开发数据流式传输应用。

流类型

Node.js 处理四种基本的流类型 −

  • Writable − 可以向其写入数据的流。

  • Readable − 可以从中读取数据的流。

  • Duplex − 同时是 Readable 和 Writable 的流。

  • Transform − Duplex 流,可以在写入和读取数据时修改或转换数据。

每种 Stream 类型都是一个 EventEmitter 实例,并在不同时间点抛出多个事件。例如,常用的事件包括 −

  • data − 当有数据可读时触发此事件。

  • end − 当没有更多数据可读时触发此事件。

  • error − 在接收或写入数据时发生任何错误时触发此事件。

  • finish − 当所有数据已刷新到底层系统时触发此事件。

本章的示例使用名为 input.txt 的文件,其中包含以下数据。

 is giving self learning content
to teach the world in simple and easy way!!!!!

Readable Stream

文件对象充当一个流,可以从中以特定大小的块读取数据。在以下示例中,我们调用 fs 模块的 createReadStream() 函数从给定文件中读取数据。可读流的 on 事件会收集文件内容,直到 end 事件被触发。

var fs = require("fs");
var data = '';

// Create a readable stream
var readerStream = fs.createReadStream('input.txt');

// Set the encoding to be utf8. 
readerStream.setEncoding('UTF8');

// Handle stream events --> 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("Program Ended");

将上述脚本保存为 main.js。运行上述 Node.js 应用程序。它将显示 input.txt 文件的内容。

Writable Stream

fs 模块的 createWriteStream() 函数创建一个可写流对象。其 write() 方法将数据存储到作为 createWriteStream() 函数参数给定的文件中。

将以下代码保存为名为 main.js 的文件。

var fs = require("fs");
var data = ` is giving self learning content
to teach the world in simple and easy way!!!!!`;

// Create a writable stream
var writerStream = fs.createWriteStream('output.txt');

// Write the data to stream with encoding to be utf8
writerStream.write(data,'UTF8');

// Mark the end of file
writerStream.end();

// Handle stream events --> finish, and error
writerStream.on('finish', function() {
   console.log("Write completed.");
});

writerStream.on('error', function(err){
   console.log(err.stack);
});

console.log("Program Ended");

现在打开当前目录中创建的 output.txt,检查它是否包含给定的数据。

管道流

管道是一种机制,将一个流输出作为另一个流的输入。通常用于从一个流获取数据,并将该流输出传递到另一个流。管道操作没有限制。现在我们展示一个管道示例,从一个文件读取并写入另一个文件。

创建一个名为 main.js 的 js 文件,内容如下 −

var fs = require("fs");

// Create a readable stream
var readerStream = fs.createReadStream('input.txt');

// Create a writable stream
var writerStream = fs.createWriteStream('output.txt');

// Pipe the read and write operations
// read input.txt and write data to output.txt
readerStream.pipe(writerStream);

console.log("Program Ended");

现在运行 main.js 查看结果 −

node main.js

验证输出。

Program Ended

打开当前目录中创建的 output.txt;它应该包含以下内容 −

 is giving self learning content
to teach the world in simple and easy way!!!!!

链式流

链式是一种机制,将一个流的输出连接到另一个流,并创建多个流操作的链。通常与管道操作一起使用。现在我们使用管道和链式首先压缩一个文件,然后解压它。

创建一个名为 main.js 的 js 文件,内容如下 −

var fs = require("fs");
var zlib = require('zlib');

// Compress the file input.txt to input.txt.gz
fs.createReadStream('input.txt')
   .pipe(zlib.createGzip())
   .pipe(fs.createWriteStream('input.txt.gz'));
  
console.log("File Compressed.");

现在运行 main.js 查看结果 −

node main.js

验证输出。

File Compressed.

你会发现 input.txt 已被压缩,并在当前目录中创建了一个文件 input.txt.gz。现在让我们使用以下代码尝试解压该文件 −

var fs = require("fs");
var zlib = require('zlib');

// Decompress the file input.txt.gz to input.txt
fs.createReadStream('input.txt.gz')
   .pipe(zlib.createGunzip())
   .pipe(fs.createWriteStream('input.txt'));
  
console.log("File Decompressed.");

现在运行 main.js 查看结果 −

node main.js

验证输出。

File Decompressed.