10. 流

流是允许您以连续方式从源读取数据或将数据写入目标的对象。

Node.js中,有四种类型的流:

  • Readable – 用于读取操作的流。
  • Writable – 用于写操作的流。
  • Duplex – Stream,可用于读写操作。
  • Transform – 一种双工流,其输出基于输入计算。

每种类型的Stream都是一个EventEmitter 实例,并在不同的时间抛出几个事件。 例如,一些常用事件是:

  • data – 当有数据可供读取时触发此事件。
  • end – 当没有更多数据要读取时,将触发此事件。
  • error – 当接收或写入数据有任何错误时触发此事件。
  • finish – 当所有数据都已刷新到底层系统时触发此事件。

本教程提供了对Streams上常用操作的基本了解。

10.1. 从溪流中读取

创建一个名为input.txt的文本文件,其中包含以下内容:

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

使用以下代码创建名为main.js的js文件:

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 main.js。验证输出:

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

10.2. 写入流

使用以下代码创建名为main.js的js文件:

var fs = require("fs");
var data = 'Simply Easy Learning';
// 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");

现在运行main.js来查看结果:$ node main.js。验证输出:

Program Ended
Write completed.

现在打开在当前目录中创建的output.txt; 它应该包含以下内容:Simply Easy Learning

10.3. 管道流

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

使用以下代码创建名为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; 它应该包含以下内容:

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

10.4. 链接流

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

使用以下代码创建名为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.

下一节:Node使用围绕标准POSIX函数的简单包装器实现文件I/O。