📜  Node.js 中的流及其类型是什么?

📅  最后修改于: 2022-05-13 01:56:35.685000             🧑  作者: Mango

Node.js 中的流及其类型是什么?

流是一种数据处理方式,可帮助我们通过读取或写入输入(文件、网络通信和任何类型的端到端信息交换)来获得顺序输出。也就是说,它们允许您从源读取数据或将其写入目标或以不间断且持续的方式执行任何其他特定任务。流对于 Node.js 来说并不是一个独特的概念,它在很长一段时间内都是 Unix 的一部分。管道运算符用于通过传递流使程序相互反应。因此,Node.js 流被用作所有流 API 的基础。

示例:当您流式传输 YouTube、Netflix、Spotify 时,不是一次性下载全部内容,而是在您继续浏览时分小块下载。另一个例子是在 Facebook 或 WhatsApp 上聊天,数据在两个人之间不断流动。
这是因为流不是一次读取内存中的所有数据,而是将其处理成更小的部分,以使大文件易于读取。它很有用,因为某些文件比您设备上的可用空间大。因此,流使此类文件可读。

流的优点:

  1. 内存效率:流是内存(空间)高效的,因为它们使您能够在处理文件之前以较小的块而不是整个内存下载文件,从而节省空间。
  2. 时间效率:流是时间效率高的,因为您开始以较小的块处理数据,因此与一般方式相比,该过程开始得更早,您必须下载整个数据才能处理它。因此,这种早期处理可以节省大量时间。
  3. 可组合数据:数据是由流的管道能力组成的,尽管代码很重,但它们可以连接在一起。这意味着一个输入通过管道传输到输出的过程不断发生。

流类型:

  1. 可读流:您可以从其中以有序方式接收和读取数据的流。但是,您不得发送任何内容。例如 fs.createReadStream() 让我们读取文件的内容。
  2. 可写流:这是您可以按顺序发送数据但不允许接收回数据的流。例如 fs.createWriteStream() 让我们将数据写入文件。
  3. 双工流:既可读又可写的流。因此,您可以一起发送和接收数据。例如 net.Socket 是一个 TCP 套接字。
  4. 转换流:它是用于修改数据或在读取数据时对其进行转换的流。变换流本质上基本上是双工的。例如,zlib.createGzip 流用于使用 gzip 压缩数据。

流中的不同操作是:

  1. 从流中读取:使用以下文本创建一个名为input.txt的文件:
    这是用于了解从流中读取的代码。

    文件名:main.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"); 
       
    // Handling data stream event
    readerStream.on("data", function(chunk) { 
        data += chunk; 
    }); 
       
    // Handling end stream event
    readerStream.on("end",function() { 
        console.log(data); 
    }); 
       
    // Handling error stream event
    readerStream.on("error", function(err) { 
        console.log(err.stack); 
    }); 
    

    使用以下命令运行main.js文件:

    $ node main.js

    上述命令的输出如下所示:

    This is a code to learn about the reading from a stream.
  2. 写入流

    文件名:main.js

    var fs = require('fs');
    var data = 'This is a code to learn"
        + " about writing in a stream.';
      
    // 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();
      
    // Handling finish stream event
    writerStream.on('finish', function () {
    });
      
    // Handling error stream event
    writerStream.on('error', function (err) {
        console.log(err.stack);
    });  
    

    使用以下命令运行main.js文件:

    $ node main.js

    执行上述命令后,将在当前目录中创建一个名为output.txt的文件,其内容如下:

    This is a code to learn about writing in a stream.
  3. 管道化流:管道化是一种操作或机制,我们提供一个数据流(可读,即源文件)的输出作为另一个流(可写,即目标文件)的输入。它通常用于从一个流中获取数据(即从源读取)并将该流的输出传递到另一个流(即写入目标),而无需自己管理流。这是使用流的最简单方法。管道操作没有限制。它用于以多种方式处理流数据。例如,从一个文件读取并将其写入另一个文件。

    使用以下文本创建一个名为input.txt的文件:

    This is a code to learn about piping the stream.

    文件名:main.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); 
    

    使用以下命令运行main.js文件:

    $ node main.js

    执行上述命令后,将在当前目录中创建一个名为output.txt的文件,其内容如下:

    This is a code to learn about piping the stream.
  4. 链接流:链接流是一种通过将一个流的输出连接到另一个流来创建多个流操作链的机制。它通常与管道操作一起使用。例如,我们将使用管道和链接来首先压缩文件,然后再解压缩。

    文件名:main.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

    现在解压上面创建的文件的代码如下所示:
    文件名:main.js

    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.

    你会发现input.txt.gz已经被解压了。