”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 使用 Node.js 流进行高效数据处理

使用 Node.js 流进行高效数据处理

发布于2024-11-09
浏览:522

Efficient Data Handling with Node.js Streams

在本文中,我们将深入研究 Node.js Streams 并了解它们如何帮助高效处理大量数据。流提供了一种处理大型数据集的优雅方式,例如读取大型文件、通过网络传输数据或处理实时信息。与一次性读取或写入整个数据的传统 I/O 操作不同,流将数据分解为可管理的块并逐块处理它们,从而实现高效的内存使用。

在本文中,我们将介绍:

  1. 什么是 Node.js Streams?
  2. Node.js 中不同类型的流。
  3. 如何创建和使用流。
  4. 流的真实用例。
  5. 使用流的优点。

什么是 Node.js 流?

Node.js 中的 stream 是连续的数据流。流对于处理 I/O 密集型任务特别有用,例如读取文件、通过网络通信或与数据库交互。流无需等待整个操作完成,而是可以分块处理数据。

流的主要特点:

  • 事件驱动:流构建在 Node.js 的事件驱动架构之上,允许在数据可用时立即处理数据。
  • 内存高效:流将数据分成块并逐块处理,减少系统的内存负载。
  • 非阻塞:Node.js 流可以异步处理大数据,而不会阻塞主事件循环。

Node.js 中的流类型

Node.js提供了四种类型的流:

  1. 可读流:可以从中读取数据的流。
  2. 可写流:可以写入数据的流。
  3. 双工流:可读可写的流(例如网络套接字)。
  4. 转换流:在读取或写入时修改或转换数据的流(例如,压缩或解压缩文件)。

使用 Node.js 流

让我们通过示例探索每种类型的流。

3.1 可读流

可读流允许您逐段读取数据,这对于处理大文件或实时数据源很有用。


const fs = require('fs');

// Create a readable stream from a large file
const readableStream = fs.createReadStream('largeFile.txt', {
    encoding: 'utf8',
    highWaterMark: 16 * 1024 // 16 KB chunk size
});

readableStream.on('data', (chunk) => {
    console.log('New chunk received:', chunk);
});

readableStream.on('end', () => {
    console.log('Reading file completed');
});


  • 在此示例中,createReadStream 方法以 16 KB 的块读取文件。
  • 每个块一旦可用就会立即处理,而不是等待整个文件加载到内存中。
  • 结束事件标志着读取过程的完成。

3.2 可写流

可写流用于将数据增量写入目的地,例如文件或网络套接字。


const fs = require('fs');

// Create a writable stream to write data to a file
const writableStream = fs.createWriteStream('output.txt');

writableStream.write('Hello, world!\n');
writableStream.write('Writing data chunk by chunk.\n');

// End the stream and close the file
writableStream.end(() => {
    console.log('File writing completed');
});


  • write 以增量方式将数据发送到文件。
  • 结束函数表示不再写入数据并关闭流。

3.3 双工流

一个双工流可以读写数据。一个常见的例子是 TCP 套接字,它可以同时发送和接收数据。


const net = require('net');

// Create a duplex stream (a simple echo server)
const server = net.createServer((socket) => {
    socket.on('data', (data) => {
        console.log('Received:', data.toString());
        // Echo the data back to the client
        socket.write(`Echo: ${data}`);
    });

    socket.on('end', () => {
        console.log('Connection closed');
    });
});

server.listen(8080, () => {
    console.log('Server listening on port 8080');
});


  • 此示例创建一个基本的回显服务器,用于从客户端读取传入数据并将其发送回。
  • 当需要双向通信时(例如在网络协议中),双工流非常方便。

3.4 变换流

A 转换流是一种特殊类型的双工流,它在数据通过时修改数据。一个常见的用例是文件压缩。


const fs = require('fs');
const zlib = require('zlib');

// Create a readable stream for a file and a writable stream for the output file
const readable = fs.createReadStream('input.txt');
const writable = fs.createWriteStream('input.txt.gz');

// Create a transform stream that compresses the file
const gzip = zlib.createGzip();

// Pipe the readable stream into the transform stream, then into the writable stream
readable.pipe(gzip).pipe(writable);

writable.on('finish', () => {
    console.log('File successfully compressed');
});


  • 管道方法用于将数据流从一个流引导到另一个流。
  • 在本例中,文件被读取,使用 Gzip 压缩,然后写入新文件。

流的实际用例

4.1 处理大文件

处理大文件(例如日志或媒体)时,将整个文件加载到内存中效率低下,并且可能会导致性能问题。流使您能够增量读取或写入大文件,从而减少内存负载。

例子:

  • 用例:流式传输视频或音频文件的媒体播放器。
  • 解决方案:使用流可确保播放器一次仅加载数据块,从而提高播放性能并减少缓冲。

4.2 实时数据处理

聊天服务器或实时仪表板等实时应用程序需要在数据到达时对其进行处理。流提供了一种有效处理这些数据、减少延迟的方法。

例子:

  • 用例:股票价格监控仪表板。
  • 解决方案:流允许服务器实时处理传入的股票价格并将更新推送到用户界面。

4.3 文件压缩与解压

压缩是流的另一个常见用例。您可以使用转换流动态压缩数据,而不是将整个文件加载到内存中。

例子:

  • 用例:在保存大文件之前压缩它们的备份系统。
  • 解决方案:流允许增量读取和压缩文件,从而节省时间并减少内存占用。

使用流的优点

  1. 内存效率:流处理数据块,从而最大限度地减少处理大文件或数据集所需的内存。
  2. 提高性能:增量处理数据减少了加载和处理大量信息所需的时间。
  3. 非阻塞 I/O:流利用 Node.js 的异步架构,允许服务器在处理数据的同时处理其他任务。
  4. 实时数据处理:流允许实时通信,非常适合需要低延迟数据传输的 Web 应用程序。
  5. 灵活性:流可以组合、管道传输和转换,使其成为复杂数据处理管道的强大工具。

结论

Node.js 流提供了一种灵活高效的方式来处理大量数据,无论您是读取文件、处理网络请求还是执行实时操作。通过将数据分解为可管理的块,流允许您处理大型数据集,而不会耗尽系统内存。

在下一篇文章中,我们将探讨 NGINX 及其在提供静态内容、负载平衡以及在 Node.js 应用程序中充当反向代理方面的作用。我们还将讨论如何集成 SSL 和加密以增强安全性。

版本声明 本文转载于:https://dev.to/imsushant12/efficient-data-handling-with-nodejs-streams-4483?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 如何从PHP中的数组中提取随机元素?
    如何从PHP中的数组中提取随机元素?
    从阵列中的随机选择,可以轻松从数组中获取随机项目。考虑以下数组:; 从此数组中检索一个随机项目,利用array_rand( array_rand()函数从数组返回一个随机键。通过将$项目数组索引使用此键,我们可以从数组中访问一个随机元素。这种方法为选择随机项目提供了一种直接且可靠的方法。
    编程 发布于2025-04-04
  • 为什么PHP的DateTime :: Modify('+1个月')会产生意外的结果?
    为什么PHP的DateTime :: Modify('+1个月')会产生意外的结果?
    使用php dateTime修改月份:发现预期的行为在使用PHP的DateTime类时,添加或减去几个月可能并不总是会产生预期的结果。正如文档所警告的那样,“当心”这些操作的“不像看起来那样直观。 考虑文档中给出的示例:这是内部发生的事情: 现在在3月3日添加另一个月,因为2月在2001年只有2...
    编程 发布于2025-04-04
  • 如何正确使用与PDO参数的查询一样?
    如何正确使用与PDO参数的查询一样?
    在pdo 中使用类似QUERIES在PDO中的Queries时,您可能会遇到类似疑问中描述的问题:此查询也可能不会返回结果,即使$ var1和$ var2包含有效的搜索词。错误在于不正确包含%符号。通过将变量包含在$ params数组中的%符号中,您确保将%字符正确替换到查询中。没有此修改,PDO...
    编程 发布于2025-04-04
  • 如何将PANDAS DataFrame列转换为DateTime格式并按日期过滤?
    如何将PANDAS DataFrame列转换为DateTime格式并按日期过滤?
    Transform Pandas DataFrame Column to DateTime FormatScenario:Data within a Pandas DataFrame often exists in various formats, including strings.使用时间数据时...
    编程 发布于2025-04-04
  • 如何在无序集合中为元组实现通用哈希功能?
    如何在无序集合中为元组实现通用哈希功能?
    在未订购的集合中的元素要纠正此问题,一种方法是手动为特定元组类型定义哈希函数,例如: template template template 。 struct std :: hash { size_t operator()(std :: tuple const&tuple)const {...
    编程 发布于2025-04-04
  • 如何将来自三个MySQL表的数据组合到新表中?
    如何将来自三个MySQL表的数据组合到新表中?
    mysql:从三个表和列的新表创建新表 答案:为了实现这一目标,您可以利用一个3-way Join。 选择p。*,d.content作为年龄 来自人为p的人 加入d.person_id = p.id上的d的详细信息 加入T.Id = d.detail_id的分类法 其中t.taxonomy =...
    编程 发布于2025-04-04
  • 为什么尽管有效代码,为什么在PHP中捕获输入?
    为什么尽管有效代码,为什么在PHP中捕获输入?
    在php ;?>" method="post">The intention is to capture the input from the text box and display it when the submit button is clicked.但是,输出...
    编程 发布于2025-04-04
  • 如何限制动态大小的父元素中元素的滚动范围?
    如何限制动态大小的父元素中元素的滚动范围?
    在交互式接口中实现垂直滚动元素的CSS高度限制问题:考虑一个布局,其中我们具有与用户垂直滚动一起移动的可滚动地图div,同时与固定的固定sidebar保持一致。但是,地图的滚动无限期扩展,超过了视口的高度,阻止用户访问页面页脚。 映射{} 因此。我们不使用jQuery的“ .aimimate(...
    编程 发布于2025-04-04
  • 您可以使用CSS在Chrome和Firefox中染色控制台输出吗?
    您可以使用CSS在Chrome和Firefox中染色控制台输出吗?
    在javascript console 中显示颜色是可以使用chrome的控制台显示彩色文本,例如红色的redors,for for for for错误消息?回答是的,可以使用CSS将颜色添加到Chrome和Firefox中的控制台显示的消息(版本31或更高版本)中。要实现这一目标,请使用以下模...
    编程 发布于2025-04-04
  • 如何简化PHP中的JSON解析以获取多维阵列?
    如何简化PHP中的JSON解析以获取多维阵列?
    php 试图在PHP中解析JSON数据的JSON可能具有挑战性,尤其是在处理多维数组时。要简化过程,建议将JSON作为数组而不是对象解析。执行此操作,将JSON_DECODE函数与第二个参数设置为true:[&&&&& && &&&&& json = JSON = JSON_DECODE($ j...
    编程 发布于2025-04-04
  • 如何在php中使用卷发发送原始帖子请求?
    如何在php中使用卷发发送原始帖子请求?
    如何使用php 创建请求来发送原始帖子请求,开始使用curl_init()开始初始化curl session。然后,配置以下选项: curlopt_url:请求 [要发送的原始数据指定内容类型,为原始的帖子请求指定身体的内容类型很重要。在这种情况下,它是文本/平原。要执行此操作,请使用包含以下标头...
    编程 发布于2025-04-04
  • Python读取CSV文件UnicodeDecodeError终极解决方法
    Python读取CSV文件UnicodeDecodeError终极解决方法
    在试图使用已内置的CSV模块读取Python中时,CSV文件中的Unicode Decode Decode Decode Decode decode Error读取,您可能会遇到错误的错误:无法解码字节 在位置2-3中:截断\ uxxxxxxxx逃脱当CSV文件包含特殊字符或Unicode的路径逃...
    编程 发布于2025-04-04
  • 如何修复\“常规错误:2006 MySQL Server在插入数据时已经消失\”?
    如何修复\“常规错误:2006 MySQL Server在插入数据时已经消失\”?
    How to Resolve "General error: 2006 MySQL server has gone away" While Inserting RecordsIntroduction:Inserting data into a MySQL database can...
    编程 发布于2025-04-04
  • 如何在Java的全屏独家模式下处理用户输入?
    如何在Java的全屏独家模式下处理用户输入?
    Handling User Input in Full Screen Exclusive Mode in JavaIntroductionWhen running a Java application in full screen exclusive mode, the usual event ha...
    编程 发布于2025-04-04
  • 如何使用组在MySQL中旋转数据?
    如何使用组在MySQL中旋转数据?
    在关系数据库中使用mySQL组使用mySQL组进行查询结果,在关系数据库中使用MySQL组,转移数据的数据是指重新排列的行和列的重排以增强数据可视化。在这里,我们面对一个共同的挑战:使用组的组将数据从基于行的基于列的转换为基于列。 Let's consider the following ...
    编程 发布于2025-04-04

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3