」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > Node.js 流:什麼、為什麼以及如何使用它們

Node.js 流:什麼、為什麼以及如何使用它們

發佈於2024-11-13
瀏覽:447

Node.js Streams: What, Why, and How to Use Them

高效处理大数据对于现代 Web 应用程序至关重要。将整个文件加载到内存中的传统方法对于处理大量数据来说并不是最佳选择。这就是 Node.js 中的 Streams 派上用场的地方。它们允许您逐段(以块的形式)处理数据,从而提高性能、减少内存使用并提高效率。在本文中,我们将探讨什么是流、为什么它们很重要以及如何在 Node.js 中有效地使用它们。

在本文中,我们将介绍:

  1. Node.js 中的流是什么?
  2. 流类型。
  3. 为什么使用流?
  4. 使用可读流读取数据。
  5. 使用可写流写入数据。
  6. 通过管道将流连接在一起。
  7. 流的实际用例。
  8. 流中的错误处理。

Node.js 中的流是什么?

Node.js 中的 Stream 是随着时间的推移读取或写入的数据序列。流允许您在生成数据时对其进行处理,而不是等待整个数据可用。这意味着您甚至可以在整个文件或请求完全可用之前开始处理数据。

流适用于:

  • 读取大文件。
  • 流式传输视频或音频数据。
  • 处理 HTTP 请求和响应。

流的类型

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

  1. 可读流:这些流允许您读取数据,例如从文件或网络套接字读取。
  2. 可写流:这些允许您写入数据,例如写入文件或通过网络发送数据。
  3. 双工流:这些都是可读可写的,这意味着您可以在同一流(例如 TCP 套接字)中读取和写入数据。
  4. 转换流:这些流允许您在数据通过时修改或转换数据,例如压缩或加密数据。

为什么使用流?

处理大数据或连续数据源时,流具有以下几个优势:

  • 高效内存使用:流以块的形式处理数据,因此它们不会将整个数据加载到内存中,从而提高内存效率。
  • 更快的处理:您可以在数据传入时开始处理数据,而不是等待整个数据集加载。
  • 非阻塞:Node.js 流是非阻塞的,这意味着它们在读取或写入数据时不会阻塞其他操作。

这对于文件读/写、HTTP 请求和提供多媒体内容等场景特别有用。

使用可读流读取数据

让我们看看如何使用 Readable Stream.

从文件中读取数据

示例:使用可读流读取文件

const fs = require('fs');

// Create a readable stream from a file
const readableStream = fs.createReadStream('input.txt', { encoding: 'utf8' });

// Handle 'data' event to read chunks of data
readableStream.on('data', (chunk) => {
    console.log('Received chunk:', chunk);
});

// Handle 'end' event when all data has been read
readableStream.on('end', () => {
    console.log('No more data.');
});

// Handle 'error' event in case of an error
readableStream.on('error', (err) => {
    console.error('An error occurred:', err.message);
});

在此示例中:

  • 我们从名为 input.txt 的文件创建一个可读流。
  • 当有数据块可用时,会触发“data”事件。
  • 当没有更多数据可供读取时,会触发 'end' 事件。

使用可写流写入数据

现在,让我们看看如何使用可写流将数据写入文件。

示例:使用可写流将数据写入文件

const fs = require('fs');

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

// Write some data to the file
writableStream.write('Hello, World!\n');
writableStream.write('This is a writable stream example.\n');

// End the stream and close the file
writableStream.end();

// Handle 'finish' event when writing is complete
writableStream.on('finish', () => {
    console.log('Writing to file completed.');
});

// Handle 'error' event in case of an error
writableStream.on('error', (err) => {
    console.error('An error occurred:', err.message);
});

在此示例中:

  • 我们创建一个可写流到名为output.txt的文件。
  • 我们使用 write() 将多个数据块写入文件。
  • 一旦写入所有数据,就会发出完成事件。

通过管道将流连接在一起

Node.js 流的强大功能之一是能够通过管道将它们连接在一起。这意味着您可以连接多个流,将数据从一个流传递到另一个流。例如,您可以从一个流中读取数据并直接将其写入另一个流。

示例:通过管道将可读流传输至可写流

const fs = require('fs');

// Create a readable stream from 'input.txt'
const readableStream = fs.createReadStream('input.txt');

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

// Pipe the readable stream to the writable stream
readableStream.pipe(writableStream);

// Handle 'finish' event for when writing completes
writableStream.on('finish', () => {
    console.log('Data has been successfully piped and written to output.txt');
});

在此示例中:

  • pipe()方法用于将数据从可读流(input.txt)传递到可写流(output.txt)。
  • 这在进程之间复制文件或传递数据时很有用。

流的实际用例

流在各种现实场景中都很有用,包括:

  1. 文件上传/下载:高效处理文件上传和下载,无需将整个文件加载到内存中。
  2. 视频/音频流:流允许您以块的形式提供或接收媒体,从而实现无缝播放。
  3. 实时数据处理:流非常适合处理数据流,例如传感器数据、日志或股票市场提要。
  4. 处理大文件:以块的形式读取和处理大型日志文件或数据集,而不耗尽系统内存。

流中的错误处理

使用流时,正确处理错误至关重要。每个流都可以发出一个错误事件,应该捕获该事件以防止崩溃。

示例:流中的错误处理

const fs = require('fs');

// Create a readable stream from a non-existent file
const readableStream = fs.createReadStream('non_existent_file.txt');

// Handle the 'error' event
readableStream.on('error', (err) => {
    console.error('An error occurred:', err.message);
});

如果文件 non_existent_file.txt 不存在,则会触发“error”事件,并记录相应的错误消息。正确的错误处理可确保您的应用程序不会意外崩溃。

结论

Node.js 流提供了一种高效且强大的方式来处理大型数据集和实时数据。通过以块的形式读取和写入数据,您可以显着减少内存使用并提高性能。无论您是使用文件系统、实时数据源还是媒体流,Node.js 中的流都可以使这些任务变得更轻松、更高效。

在本文中,我们介绍了 Node.js 流的基础知识,包括读取和写入流、通过管道传输流以及实际用例。我们还讨论了如何有效处理错误以确保基于流的应用程序的稳健性。

通过掌握流,您可以释放 Node.js 构建可扩展、高效和高性能应用程序的全部潜力。

接下来,我们将继续我们的系列,深入探讨更高级的主题,例如扩展 Node.js 应用程序和使用 NGINX 提供静态内容。敬请关注!

版本聲明 本文轉載於:https://dev.to/imsushant12/nodejs-streams-what-why-and-how-to-use-them-5d4f?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 如何使用FormData()處理多個文件上傳?
    如何使用FormData()處理多個文件上傳?
    )處理多個文件輸入時,通常需要處理多個文件上傳時,通常是必要的。 The fd.append("fileToUpload[]", files[x]); method can be used for this purpose, allowing you to send multi...
    程式設計 發佈於2025-04-30
  • 如何在其容器中為DIV創建平滑的左右CSS動畫?
    如何在其容器中為DIV創建平滑的左右CSS動畫?
    通用CSS動畫,用於左右運動 ,我們將探索創建一個通用的CSS動畫,以向左和右移動DIV,從而到達其容器的邊緣。該動畫可以應用於具有絕對定位的任何div,無論其未知長度如何。 問題:使用左直接導致瞬時消失 更加流暢的解決方案:混合轉換和左 [並實現平穩的,線性的運動,我們介紹了線性的轉換。...
    程式設計 發佈於2025-04-30
  • PHP SimpleXML解析帶命名空間冒號的XML方法
    PHP SimpleXML解析帶命名空間冒號的XML方法
    在php 很少,請使用該限制很大,很少有很高。例如:這種技術可確保可以通過遍歷XML樹和使用兒童()方法()方法的XML樹和切換名稱空間來訪問名稱空間內的元素。
    程式設計 發佈於2025-04-30
  • MySQL中字符串作為主鍵對性能影響大嗎?
    MySQL中字符串作為主鍵對性能影響大嗎?
    MySQL數據庫中使用字符串作為主鍵的性能影響 在創建數據庫時,主鍵是至關重要的組成部分,它唯一標識每一行數據,對數據完整性和查詢效率起著重要作用。雖然整數由於其數值特性而通常用作主鍵,但在某些情況下,字符串可能更合適。 性能影響 從技術上講,字符串可以在MySQL數據庫中用作主鍵。但是,值得考...
    程式設計 發佈於2025-04-30
  • eval()vs. ast.literal_eval():對於用戶輸入,哪個Python函數更安全?
    eval()vs. ast.literal_eval():對於用戶輸入,哪個Python函數更安全?
    稱量()和ast.literal_eval()中的Python Security 在使用用戶輸入時,必須優先確保安全性。強大的Python功能Eval()通常是作為潛在解決方案而出現的,但擔心其潛在風險。 This article delves into the differences betwee...
    程式設計 發佈於2025-04-30
  • 您如何在Laravel Blade模板中定義變量?
    您如何在Laravel Blade模板中定義變量?
    在Laravel Blade模板中使用Elegance 在blade模板中如何分配變量對於存儲以後使用的數據至關重要。在使用“ {{}}”分配變量的同時,它可能並不總是最優雅的解決方案。 幸運的是,Blade通過@php Directive提供了更優雅的方法: $ old_section =...
    程式設計 發佈於2025-04-30
  • 如何從Google API中檢索最新的jQuery庫?
    如何從Google API中檢索最新的jQuery庫?
    從Google APIS 問題中提供的jQuery URL是版本1.2.6。對於檢索最新版本,以前有一種使用特定版本編號的替代方法,它是使用以下語法:獲取最新版本:未壓縮)While these legacy URLs still remain in use, it is recommended ...
    程式設計 發佈於2025-04-30
  • 為什麼PHP的DateTime :: Modify('+1個月')會產生意外的結果?
    為什麼PHP的DateTime :: Modify('+1個月')會產生意外的結果?
    使用php dateTime修改月份:發現預期的行為在使用PHP的DateTime類時,添加或減去幾個月可能並不總是會產生預期的結果。正如文檔所警告的那樣,“當心”這些操作的“不像看起來那樣直觀。 ; $ date->修改('1個月'); //前進1個月 echo $ date->...
    程式設計 發佈於2025-04-30
  • 如何在Java中正確顯示“ DD/MM/YYYY HH:MM:SS.SS”格式的當前日期和時間?
    如何在Java中正確顯示“ DD/MM/YYYY HH:MM:SS.SS”格式的當前日期和時間?
    如何在“ dd/mm/yyyy hh:mm:mm:ss.ss”格式“ gormat 解決方案:的,請訪問量很大,並應為procectiquiestate的,並在整個代碼上正確格式不多: java.text.simpledateformat; 導入java.util.calendar; 導入java...
    程式設計 發佈於2025-04-30
  • 為什麼HTML無法打印頁碼及解決方案
    為什麼HTML無法打印頁碼及解決方案
    無法在html頁面上打印頁碼? @page規則在@Media內部和外部都無濟於事。 HTML:Customization:@page { margin: 10%; @top-center { font-family: sans-serif; font-weight: ...
    程式設計 發佈於2025-04-30
  • HTML格式標籤
    HTML格式標籤
    HTML 格式化元素 **HTML Formatting is a process of formatting text for better look and feel. HTML provides us ability to format text without us...
    程式設計 發佈於2025-04-30
  • 組件驅動CSS框架:開發者的新選擇
    組件驅動CSS框架:開發者的新選擇
    核心要点 Web Components日益流行,对能够处理这种开发类型的CSS框架的需求也日益增长。传统的CSS框架(如Bootstrap或Foundation)由于其广泛的内置样式和代码,可能会限制开发人员使用Web Components。 组件驱动型CSS框架(如Pattern Lab、SUI...
    程式設計 發佈於2025-04-30
  • 如何在Chrome中居中選擇框文本?
    如何在Chrome中居中選擇框文本?
    選擇框的文本對齊:局部chrome-inly-ly-ly-lyly solument 您可能希望將文本中心集中在選擇框中,以獲取優化的原因或提高可訪問性。但是,在CSS中的選擇元素中手動添加一個文本 - 對屬性可能無法正常工作。 初始嘗試 state)</option> < o...
    程式設計 發佈於2025-04-30
  • 在Java中使用for-to-loop和迭代器進行收集遍歷之間是否存在性能差異?
    在Java中使用for-to-loop和迭代器進行收集遍歷之間是否存在性能差異?
    For Each Loop vs. Iterator: Efficiency in Collection TraversalIntroductionWhen traversing a collection in Java, the choice arises between using a for-...
    程式設計 發佈於2025-04-30
  • 如何高效地在一個事務中插入數據到多個MySQL表?
    如何高效地在一個事務中插入數據到多個MySQL表?
    mySQL插入到多個表中,該數據可能會產生意外的結果。雖然似乎有多個查詢可以解決問題,但將從用戶表的自動信息ID與配置文件表的手動用戶ID相關聯提出了挑戰。 使用Transactions和last_insert_id() 插入用戶(用戶名,密碼)值('test','tes...
    程式設計 發佈於2025-04-30

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3