NodeJS 中Stream 的基本使用

yizhihongxing

NodeJS中Stream是一种非常重要的数据处理工具,它可以帮助我们高效地处理大量数据,在文件读写、网络传输等多个场景下都有广泛应用。下面我们来详细讲解NodeJS中Stream的基本使用。

什么是Stream

流(Stream)是Node.js中处理流式数据的一个抽象接口。Stream有四种类型:Readable、Writable、Duplex、Transform。在Stream中,数据是以块(chunk)为单位流动的,而不是一次性将所有数据读取到内存中。这使得在读写大量数据时不会因为内存不足而出现问题。

在Node.js中,大多数的核心API都提供了Stream的支持,比如文件读写和网络传输等。除此之外,我们也可以自定义Stream来满足特定的需求。

Stream的基本用法

创建Readable Stream

使用fs.createReadStream()来创建一个Readable Stream来读取文件的内容。

const fs = require('fs');

const readStream = fs.createReadStream('./example.txt');

readStream.on('data', (chunk) => {
  console.log(chunk.toString());  // 输出读取到的数据块
});

readStream.on('end', () => {
  console.log('读取完成');
});

readStream.on('error', (err) => {
  console.error('发生错误', err);
});

上面的代码中,我们通过fs.createReadStream()方法读取了当前目录下的example.txt文件,并将其转换为一个可读流(Readable Stream)。然后,我们通过readStream.on('data', ...)监听了data事件,当数据块可读取时触发该事件,我们将读取到的数据块输出到控制台。readStream.on('end', ...)监听end事件,当所有数据块读取完毕时触发该事件,我们输出"读取完成"的信息。readStream.on('error', ...)监听error事件,当读取过程中发生了错误时触发该事件,我们将错误信息输出到控制台。

我们也可以通过继承Readable类来创建自定义的可读流。

const { Readable } = require('stream');

class MyReadable extends Readable {
  constructor(options) {
    super(options);
    this.data = ['a', 'b', 'c'];
  }

  _read() {
    if (!this.data.length) {
      this.push(null);
    } else {
      this.push(this.data.shift());
    }
  }
}

const myReadable = new MyReadable();

myReadable.on('data', (chunk) => {
  console.log(chunk.toString());
});

myReadable.on('end', () => {
  console.log('读取完成');
});

myReadable.on('error', (err) => {
  console.error('发生错误', err);
});

上面的代码中,我们通过继承Readable类创建了一个自定义的可读流MyReadable,并在构造函数中初始化了一个字符串数组data来表示数据源。我们重写了MyReadable_read()方法,每次调用该方法时,我们将data数组中的一个元素推到流中,推完后从数组中删除该元素。当没有数据可以推送时,我们通过调用this.push(null)来告诉流读取结束。

创建完成后,我们通过myReadable.on('data', ...)监听data事件,当数据块可读取时触发该事件,我们将读取到的数据块输出到控制台。myReadable.on('end', ...)监听end事件,当所有数据块读取完毕时触发该事件,我们输出"读取完成"的信息。myReadable.on('error', ...)监听error事件,当读取过程中发生了错误时触发该事件,我们将错误信息输出到控制台。

创建Writable Stream

使用fs.createWriteStream()来创建一个Writable Stream来写入文件的内容。

const fs = require('fs');

const writeStream = fs.createWriteStream('./example.txt');

writeStream.write('Hello, World!\n');
writeStream.write('Hello, Node.js!\n');
writeStream.end('End of file.');

writeStream.on('finish', () => {
  console.log('写入完成');
});

writeStream.on('error', (err) => {
  console.error('发生错误', err);
});

上面的代码中,我们通过fs.createWriteStream()方法创建可写流(Writable Stream)并指定要写入的文件。然后,我们通过writeStream.write()方法向流中写入一些数据,并在最后通过writeStream.end()方法告诉流写入结束。注意,如果不调用writeStream.end()方法,流将不会结束,也就不会触发finish事件。最后,我们通过writeStream.on('finish', ...)监听finish事件,当所有数据块写入完成时触发该事件,我们输出"写入完成"的信息。writeStream.on('error', ...)监听error事件,当写入过程中发生了错误时触发该事件,我们将错误信息输出到控制台。

我们也可以通过继承Writable类来创建自定义的可写流。

const { Writable } = require('stream');

class MyWritable extends Writable {
  constructor(options) {
    super(options);
    this.data = '';
  }

  _write(chunk, encoding, callback) {
    this.data += chunk.toString();
    callback();
  }
}

const myWritable = new MyWritable();

myWritable.write('Hello, World!\n');
myWritable.write('Hello, Node.js!\n');
myWritable.end('End of file.');

myWritable.on('finish', () => {
  console.log(myWritable.data);
  console.log('写入完成');
});

myWritable.on('error', (err) => {
  console.error('发生错误', err);
});

上面的代码中,我们通过继承Writable类创建了一个自定义的可写流MyWritable。在构造函数中,我们初始化了一个字符串data来表示写入的内容。我们重写了MyWritable_write()方法,该方法会在每次写入数据时被调用,我们将写入的数据块转换为字符串,并拼接到data字符串中。当所有数据块写入完毕时,我们通过调用callback()告诉流本次写入完成。最后,我们通过myWritable.on('finish', ...)监听finish事件,当所有数据块写入完成时触发该事件,我们输出写入的内容和"写入完成"的信息。myWritable.on('error', ...)监听error事件,当写入过程中发生了错误时触发该事件,我们将错误信息输出到控制台。

结语

以上就是NodeJS中Stream的基本使用方法。通过学习这些内容,我们可以使用Stream高效地处理大量数据。如果你还想进一步了解Stream的详细内容和使用方法,可以参考Node.js官方文档。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:NodeJS 中Stream 的基本使用 - Python技术站

(0)
上一篇 2023年5月14日
下一篇 2023年5月14日

相关文章

  • Windows下PyTorch开发环境安装教程

    安装Python 在Windows上,首先需要安装Python环境,可以去Python官网(https://www.python.org/downloads/)下载最新的Python安装包,推荐下载Python3.x(3.6及以上版本)。 选择相应的版本下载后,双击运行,按照提示进行安装。 安装PyTorch 推荐使用pip安装PyTorch,打开Windo…

    python 2023年5月14日
    00
  • 查找两个数据框架共享的列

    要查找两个数据框架共享的列,可以采用以下步骤: 获取数据框架的列名列表 首先,需要获取数据框架的列名列表,可以使用 colnames() 或 names() 函数获得。这两个函数的作用一样,用法也一样,我们以 colnames() 函数为例: df1 <- data.frame(name = c("A", "B"…

    python-answer 2023年3月27日
    00
  • 解决pycharm 误删掉项目文件的处理方法

    当使用PyCharm开发Python项目时,有时会误删掉项目文件,这时需要进行一些处理,以恢复误删文件,下面详细介绍“解决pycharm误删掉项目文件的处理方法”的完整攻略: 确认文件是否在回收站 PyCharm删除的文件会被默认移动到系统的回收站中,在回收站中可通过恢复操作来找回被删除的文件。前提是在删除文件后没有进行过系统清理,则可以在回收站中找回删除的…

    python 2023年5月14日
    00
  • python杀死一个线程的方法

    当使用Python创建一个线程的时候,有时候需要中断这个线程,此时需要使用Python的同步原语同时配合Python的一些API实现线程中断。 下面是Python杀死一个线程的方法攻略: 原理 通过设置标志位,让线程在执行时依据标志位自行退出,这样达到了杀死线程的目的。 方案 实现线程的安全中断具体可以分为以下两个步骤: 1. 设定标志位 首先,在需要中断线…

    python 2023年5月14日
    00
  • pandas object格式转float64格式的方法

    将pandas object格式的数据转换为float64格式的方法可以使用astype()函数实现。astype()函数接收一个数据类型作为输入参数,并返回一个对应类型的数据副本。 具体示例代码如下: import pandas as pd # 示例数据 data = pd.DataFrame({‘A’: [‘1’, ‘2’, ‘3’, ‘4’], ‘B’…

    python 2023年5月14日
    00
  • 如何找到Pandas数据框架的横截面

    要找到Pandas数据框架的横截面,我们需要用到Pandas库中的DataFrame.loc方法和选择器。下面是具体的步骤和示例: 步骤1:导入Pandas库和数据框架 首先,我们要导入Pandas库,并用其读取一个示例数据集,例如Titanic数据集: import pandas as pd titanic_df = pd.read_csv(‘titani…

    python-answer 2023年3月27日
    00
  • pandas 层次化索引的实现方法

    下面是关于“pandas层次化索引的实现方法”的完整攻略,包含以下内容: 一、什么是层次化索引 层次化索引(hierarchical indexing,也称为多级索引)是 pandas 中一项重要的功能。它使得我们可以在一个轴上拥有多个(两个以上)的索引级别。 以 DataFrame 为例,可以通过设置多个行或者列索引级别来获得层次化索引。这种方式下,每个轴…

    python 2023年5月14日
    00
  • 如何在Python中从Pandas数据框中获取最大值

    从 Pandas 数据框中获取最大值,可通过以下步骤完成: 首先,要导入 Pandas 库,如下所示: import pandas as pd 然后,创建一个DataFrame对象。例如: data = {‘name’: [‘John’, ‘Jane’, ‘Sam’, ‘Sylvester’, ‘Pete’], ‘age’: [23, 29, 21, 35,…

    python-answer 2023年3月27日
    00
合作推广
合作推广
分享本页
返回顶部