深入nodejs中流(stream)的理解

yizhihongxing

理解 Node.js 中的流(stream)非常重要,因为在处理大量数据或网络流时,流是一种高效而可靠的方式。本文将深入介绍 Node.js 中的流概念和使用方法,包括流的类型、创建和使用流、以及流的事件和操作。

流的类型

在 Node.js 中,流可以分为四类:

  1. 可读流(Readable Stream):从源头读取数据。
  2. 可写流(Writable Stream):向目标写入数据。
  3. 双工流(Duplex Stream):既可以读取数据也可以写入数据。常见的例子是 Socket。
  4. 转换流(Transform Stream):属于双工流的一种,会修改从源头读取的数据,再写入到目标中。常见的例子是 zlib 流,用于压缩和解压数据。

创建和使用流

要使用一个流,首先需要创建一个实例,并指定源头和目标(如果有的话)。例如,要创建一个可读流并从文件中读取数据,可以使用 fs.createReadStream(),如下所示:

const fs = require('fs');
const rs = fs.createReadStream('/path/to/file');

创建转换流和可写流的方法类似,分别使用 stream.Transformfs.createWriteStream,例如:

const stream = require('stream');
const ts = new stream.Transform();
const ws = fs.createWriteStream('/path/to/file');

流的事件和操作

创建流的实例后,可以使用事件来监听它的状态。

data 事件:当有数据可读时,会触发 data 事件,可以使用如下代码监听:

rs.on('data', function(chunk) {
  console.log(`Received ${chunk.length} bytes of data.`);
});

其他流事件还包括:end(数据读取完毕),error(发生错误)和 finish(数据写入完毕)。

有一些常见的流处理操作:

  1. pipe() 函数:将一个可读流连接到一个可写流中,自动调节速度和缓存,可实现高效处理大量数据,例如:

js
rs.pipe(ts).pipe(ws);

  1. unpipe() 函数:从目标中移除可读流,例如:

js
rs.unpipe(ts);

  1. pause()resume() 函数:分别暂停和恢复流的读写,例如:

js
rs.pause();
rs.resume();

示例说明

以下是两个使用流的示例:

示例一

在处理大型日志文件时,可以使用可读流逐行读取文件,并使用转换流来执行某些操作,而不必一次性将整个文件读入内存。例如,以下是用于处理日志文件的转换流示例:

class LogTransform extends stream.Transform {
  constructor(options) {
    super(options);
    this.tail = '';
  }
  _transform(chunk, encoding, callback) {
    const lines = (this.tail + chunk)
      .split('\n')
      .filter((line, index, array) => {
        return line.length > 0 || index < array.length - 1;
      });
    this.tail = lines.pop();
    lines.forEach(line => this.push(`${line}\n`));
    callback();
  }
  _flush(callback) {
    if (this.tail.length > 0) {
      this.push(`${this.tail}\n`);
    }
    callback();
  }
}

const fs = require('fs');
const rs = fs.createReadStream('/path/to/logfile');
const ts = new LogTransform();
rs.pipe(ts).pipe(process.stdout);

该转换流将文件转换成逐行格式,并将格式化后的数据写入输出流中,以便显示。在这个示例中,process.stdout 是指标准输出流(console.log 和 process.stdout.write 使用的流)。

示例二

在从网络中读取数据时,可以使用可读流和双工流的组合。例如,以下是使用 net 模块创建 TCP 服务器并处理客户端请求的示例:

const net = require('net');

const server = net.createServer(client => {
  console.log(`Client ${client.remoteAddress}:${client.remotePort} connected.`);
  const ts = new stream.Transform();
  ts._transform = (chunk, encoding, callback) => {
    const data = chunk.toString().toUpperCase();
    callback(null, data);
  };
  client.pipe(ts).pipe(client);
});

server.on('error', error => {
  console.error(`Server error: ${error.message}`);
});

server.listen(8888, () => {
  console.log(`Server listening on port ${server.address().port}...`);
});

当一个客户端连接到该服务器时,服务器会创建一个新的转换流,处理从客户端读取的数据,将它们转换为大写字母,并将结果返回给客户端。在这个示例中,“客户端”连接到同一台计算机的端口 8888。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:深入nodejs中流(stream)的理解 - Python技术站

(0)
上一篇 2023年6月8日
下一篇 2023年6月8日

相关文章

  • 详解Node.js如何处理ES6模块

    下面我来详细讲解“详解Node.js如何处理ES6模块”的完整攻略。 什么是ES6模块 ES6模块是一种在 JavaScript 中组织代码的标准方式,它可以帮助我们将代码分割到单独的文件中,以便更好地组织和管理代码。 ES6模块的一个主要特点是通过 import 和 export 关键字来定义模块之间的依赖和导出。在导入模块时,我们可以使用 import …

    node js 2023年6月8日
    00
  • Node中完整的 node addon 实现流程

    下面将为你详细讲解 Node 中完整的 Node addon 实现流程。 1. Node addon 是什么? Node addon 是指可以使用 C++ 代码编写并且在 Node.js 中使用的扩展。它允许 Node.js 的用户在 JavaScript 中使用 C/C++ 代码实现高效的模块和操作,以及与原生代码交互,从而提高 Node.js 在高性能计…

    node js 2023年6月8日
    00
  • JavaScript 用Node.js写Shell脚本[译]

    让我来详细讲解“JavaScript 用Node.js写Shell脚本[译]”的完整攻略。 什么是 Shell 脚本? Shell 脚本是一种运行在 Unix/Linux 系统上的脚本,用于自动执行一系列的命令或操作。通常用 Shell 脚本来完成常规的任务,如备份数据、自动部署应用程序等。 Shell 脚本通常是使用 Shell 编程语言编写的。Shell…

    node js 2023年6月8日
    00
  • nodeJs爬虫获取数据简单实现代码

    下面是关于“nodeJs爬虫获取数据简单实现代码”的完整攻略。 1. 前言 在讲解具体实现方法之前,我们需要了解一下什么是爬虫及其应用场景。 1.1 什么是爬虫 爬虫是指按照一定的规则自动从互联网上抓取信息的程序,也称网络爬虫、网络机器人。其工作模式基本上类似于人工去浏览网页,寻找信息,但爬虫可以在很短时间内处理大量信息。 1.2 爬虫的应用场景 在互联网上…

    node js 2023年6月8日
    00
  • koa2的中间件功能及应用示例

    Koa2的中间件功能及应用示例 1. Koa2中间件的概念和作用 Koa2是一种轻量级的Web开发框架,使用Node.js平台的HTTP服务构建。类似于Express,它主要是通过中间件函数来处理 HTTP 请求。Koa2中间件是一个函数,它可以带有三个参数,分别为context对象、next函数和可选的错误处理函数。其中,context对象是一个对HTTP…

    node js 2023年6月8日
    00
  • 前端AI机器学习在浏览器中训练模型

    要在浏览器中进行前端AI机器学习的模型训练,可以通过TensorFlow.js这个JavaScript库来实现。下面是完整攻略: 第一步:准备数据集 在训练模型之前,首先需要准备好数据集,这通常是一个带有标签的数据集。可以利用已有的公共数据集(比如MNIST手写数字数据集),也可以自己收集数据。 第二步:加载数据集 需要将数据集加载到浏览器中,可以使用浏览器…

    node js 2023年6月8日
    00
  • 如何在node的express中使用socket.io

    想要在Node的Express中使用Socket.io,需要遵循以下步骤: 安装socket.io和express模块: npm install –save socket.io express 启用服务器和Socket.io: const express = require(‘express’); const http = require(‘http’);…

    node js 2023年6月8日
    00
  • JavaScript异步队列进行try catch时的问题解决

    JavaScript中的异步操作很常见,例如通过ajax请求获取数据,或者使用setTimeout等函数延时执行代码。在异步操作中,代码不会按照原来的顺序依次执行,而是先执行后续的代码,异步操作完成后再回来执行该操作后面的代码。这种机制带来了很多便利,同时也带来了不少问题,其中包括try catch无法捕获异步代码中的错误。 以下是解决该问题的完整攻略: 1…

    node js 2023年6月8日
    00
合作推广
合作推广
分享本页
返回顶部