」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 使用 Node.js 流進行高效能資料處理

使用 Node.js 流進行高效能資料處理

發佈於2024-11-09
瀏覽:343

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]刪除
最新教學 更多>
  • 為什麼不使用CSS`content'屬性顯示圖像?
    為什麼不使用CSS`content'屬性顯示圖像?
    在Firefox extemers屬性為某些圖像很大,&& && && &&華倍華倍[華氏華倍華氏度]很少見,卻是某些瀏覽屬性很少,尤其是特定於Firefox的某些瀏覽器未能在使用內容屬性引用時未能顯示圖像的情況。這可以在提供的CSS類中看到:。 googlepic { 內容:url(&...
    程式設計 發佈於2025-04-08
  • 如何使用Python理解有效地創建字典?
    如何使用Python理解有效地創建字典?
    在python中,詞典綜合提供了一種生成新詞典的簡潔方法。儘管它們與列表綜合相似,但存在一些顯著差異。 與問題所暗示的不同,您無法為鑰匙創建字典理解。您必須明確指定鍵和值。 For example:d = {n: n**2 for n in range(5)}This creates a dict...
    程式設計 發佈於2025-04-08
  • Java是否允許多種返回類型:仔細研究通用方法?
    Java是否允許多種返回類型:仔細研究通用方法?
    在Java中的多個返回類型:一種誤解類型:在Java編程中揭示,在Java編程中,Peculiar方法簽名可能會出現,可能會出現,使開發人員陷入困境,使開發人員陷入困境。 getResult(string s); ,其中foo是自定義類。該方法聲明似乎擁有兩種返回類型:列表和E。但這確實是如此嗎...
    程式設計 發佈於2025-04-08
  • 您可以使用CSS在Chrome和Firefox中染色控制台輸出嗎?
    您可以使用CSS在Chrome和Firefox中染色控制台輸出嗎?
    在javascript console 中顯示顏色是可以使用chrome的控制台顯示彩色文本,例如紅色的redors,for for for for錯誤消息? 回答是的,可以使用CSS將顏色添加到Chrome和Firefox中的控制台顯示的消息(版本31或更高版本)中。要實現這一目標,請使用以下...
    程式設計 發佈於2025-04-08
  • 為什麼PYTZ最初顯示出意外的時區偏移?
    為什麼PYTZ最初顯示出意外的時區偏移?
    與pytz 最初從pytz獲得特定的偏移。例如,亞洲/hong_kong最初顯示一個七個小時37分鐘的偏移: 差異源利用本地化將時區分配給日期,使用了適當的時區名稱和偏移量。但是,直接使用DateTime構造器分配時區不允許進行正確的調整。 example pytz.timezone(&#...
    程式設計 發佈於2025-04-08
  • 如何配置Pytesseract以使用數字輸出的單位數字識別?
    如何配置Pytesseract以使用數字輸出的單位數字識別?
    Pytesseract OCR具有單位數字識別和僅數字約束 在pytesseract的上下文中,在配置tesseract以識別單位數字和限制單個數字和限制輸出對數字可能會提出質疑。 To address this issue, we delve into the specifics of Te...
    程式設計 發佈於2025-04-08
  • 如何使用FormData()處理多個文件上傳?
    如何使用FormData()處理多個文件上傳?
    )處理多個文件輸入時,通常需要處理多個文件上傳時,通常是必要的。 The fd.append("fileToUpload[]", files[x]); method can be used for this purpose, allowing you to send multi...
    程式設計 發佈於2025-04-08
  • 如何將來自三個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-08
  • 如何正確使用與PDO參數的查詢一樣?
    如何正確使用與PDO參數的查詢一樣?
    在pdo 中使用類似QUERIES在PDO中的Queries時,您可能會遇到類似疑問中描述的問題:此查詢也可能不會返回結果,即使$ var1和$ var2包含有效的搜索詞。錯誤在於不正確包含%符號。 通過將變量包含在$ params數組中的%符號中,您確保將%字符正確替換到查詢中。沒有此修改,PD...
    程式設計 發佈於2025-04-08
  • 為什麼不````''{margin:0; }`始終刪除CSS中的最高邊距?
    為什麼不````''{margin:0; }`始終刪除CSS中的最高邊距?
    在CSS 問題:不正確的代碼: 全球範圍將所有餘量重置為零,如提供的代碼所建議的,可能會導致意外的副作用。解決特定的保證金問題是更建議的。 例如,在提供的示例中,將以下代碼添加到CSS中,將解決餘量問題: body H1 { 保證金頂:-40px; } 此方法更精確,避免了由全局保證金重置...
    程式設計 發佈於2025-04-08
  • Android如何向PHP服務器發送POST數據?
    Android如何向PHP服務器發送POST數據?
    在android apache httpclient(已棄用) httpclient httpclient = new defaulthttpclient(); httppost httppost = new httppost(“ http://www.yoursite.com/script.p...
    程式設計 發佈於2025-04-08
  • 找到最大計數時,如何解決mySQL中的“組函數\”錯誤的“無效使用”?
    找到最大計數時,如何解決mySQL中的“組函數\”錯誤的“無效使用”?
    如何在mySQL中使用mySql 檢索最大計數,您可能會遇到一個問題,您可能會在嘗試使用以下命令:理解錯誤正確找到由名稱列分組的值的最大計數,請使用以下修改後的查詢: 計數(*)為c 來自EMP1 按名稱組 c desc訂購 限制1 查詢說明 select語句提取名稱列和每個名稱...
    程式設計 發佈於2025-04-08
  • 如何在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-08
  • 如何使用“ JSON”軟件包解析JSON陣列?
    如何使用“ JSON”軟件包解析JSON陣列?
    parsing JSON與JSON軟件包 QUALDALS:考慮以下go代碼:字符串 } func main(){ datajson:=`[“ 1”,“ 2”,“ 3”]`` arr:= jsontype {} 摘要:= = json.unmarshal([] byte(...
    程式設計 發佈於2025-04-08
  • 為什麼使用Firefox後退按鈕時JavaScript執行停止?
    為什麼使用Firefox後退按鈕時JavaScript執行停止?
    導航歷史記錄問題:JavaScript使用Firefox Back Back 此行為是由瀏覽器緩存JavaScript資源引起的。要解決此問題並確保在後續頁面訪問中執行腳本,Firefox用戶應設置一個空功能。 警報'); }; alert('inline Alert')...
    程式設計 發佈於2025-04-08

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

Copyright© 2022 湘ICP备2022001581号-3