Node.js Streams 教程:檔案流,管道

在本教程中,你將學習

Node.js 中的 Filestream

Node 廣泛使用流作為資料傳輸機制。

例如,當你使用 console.log 函式向控制檯輸出任何內容時,實際上是使用流將資料傳送到控制檯。

Node.js 還能夠從檔案中流式傳輸資料,以便可以對檔案進行適當的讀寫。我們現在看一個如何使用流來讀取和寫入檔案的示例。對於此示例,我們需要遵循下面提到的步驟

步驟 1: 建立一個名為 data.txt 的檔案,其中包含以下資料。假設此檔案儲存在本地計算機的 D 盤上。

Tutorial on Node.js
Introduction
Events
Generators
Data Connectivity
Using Jasmine

步驟 2: 編寫將使用流來從檔案中讀取資料的相關程式碼。

var fs = require("fs");
var stream;
stream = fs.createReadStream("D://data.txt");
stream.on("data", function(data) {
    var chunk = data.toString();
    console.log(chunk);
}); 

程式碼說明: -

  1. 我們首先需要包含 fs 模組,其中包含建立流所需的所有功能。
  2. 接下來,我們使用方法 createReadStream 建立可讀流。作為輸入,我們給出 data.txt 檔案的位置。
  3. steam.on 函式是一個事件處理程式,在其中,我們將第一個引數指定為 data。這意味著只要資料來自檔案的流,然後執行回撥函式。在我們的例子中,我們定義了一個回撥函式,它將執行 2 個基本步驟。第一種是將從檔案讀取的資料轉換為字串。第二種方法是將轉換後的字串作為輸出傳送到控制檯。
  4. 我們將從資料流中讀取每個資料塊並將其轉換為字串。
  5. 最後,我們將每個字串轉換塊的輸出傳送到控制檯。

輸出:

Tutorial on Node.js
Introduction
Events
Generators
Data Connectivity
Using Jasmine

如果程式碼執行正確,你將在控制檯中看到上述輸出。此輸出將與 data.txt 檔案中的輸出相同。

寫入檔案

以同樣的方式,我們建立一個讀取流,我們也可以建立一個寫入流來將資料寫入檔案。讓我們首先建立一個沒有名為 data.txt 的內容的空檔案。我們假設這個檔案放在我們電腦的 D 盤中。

以下程式碼顯示了我們如何將資料寫入檔案。

var fs = require("fs");
var stream;
stream = fs.createWriteStream("D://data.txt");
stream.write("Tutorial on Node.js")
stream.write("Introduction")
stream.write("Events")
stream.write("Generators")
stream.write("Data Connectivity")
stream.write("Using Jasmine") 

程式碼說明: -

  1. 我們使用方法 createWriteStream 建立可寫流。作為輸入,我們給出 data.txt 檔案的位置。
  2. 接下來,我們使用 stream.write 方法將不同的文字行寫入文字檔案。流將負責將此資料寫入 data.txt 檔案。

如果開啟 data.txt 檔案,現在將在檔案中看到以下資料

Tutorial on Node.js
Introduction
Events
Generators
Data Connectivity
Using Jasmine

Node.js 中的管道

在 Node 應用程式中,可以使用 pipe() 方法將流連線在一起,該方法有兩個引數:

  • 作為資料和目標的必需可寫流
  • 用於傳入選項的可選物件。

如果要將資料從一個檔案傳輸到另一個檔案,則使用管道的典型示例。

那麼讓我們看一個如何使用管道將資料從一個檔案傳輸到另一個檔案的示例。

步驟 1: 建立一個名為 datainput.txt 的檔案,其中包含以下資料。假設此檔案儲存在本地計算機的 D 驅動器上。

Tutorial on Node.js
Introduction
Events
Generators
Data Connectivity
Using Jasmine

步驟 2: 建立一個名為 dataOutput.txt 的空白空檔案,並將其放在本地計算機的 D 驅動器上。

步驟 3: 編寫以下程式碼以執行從 datainput.txt 檔案到 dataOutput.txt 檔案的資料傳輸。

var fs = require("fs"); 
var readstream = fs.createReadStream("D://datainput.txt");

var writeStream = fs.createWriteStream("D://dataoutput.txt");

readstream.pipe(writeStream);

程式碼說明: -

  1. 我們首先為 datainput.txt 檔案建立一個 readstream,其中包含我們需要傳輸到新檔案的所有資料。
  2. 然後,我們需要為 dataOutput.txt 檔案建立一個 writestream,這是我們的空檔案,是從 datainput.txt 檔案傳輸資料的目的地。
  3. 然後,我們使用 pipe 命令將資料從讀取流傳輸到寫入流。pipe 命令將獲取進入讀取流的所有資料,並將其推送到寫入流。

如果現在開啟 dataOutput.txt 檔案,你將看到 datainput.txt 檔案中存在的所有資料。

Node.js 中的事件

事件是 Node.js 中的關鍵概念之一,有時 Node.js 被稱為事件驅動框架。

基本上,事件就是發生的事情。例如,如果建立與資料庫的連線,則觸發資料庫連線事件。事件驅動程式設計是為了建立在觸發特定事件時觸發的函式。

讓我們看一下在 Node.js 中定義事件的基本示例。

我們將建立一個名為 data_received 的事件。觸發此事件時,文字 data_received 將傳送到控制檯。

var events = require('events');
var eventEmitter = new events.EventEmitter();
eventEmitter.on('data_received', function() {
    console.log('data received succesfully.');
});
eventEmitter.emit('data_received'); 

程式碼說明: -

  1. 使用 require 函式包含 events 模組。使用此模組,你將能夠在 Node.js 中建立事件。
  2. 建立一個新的事件發射器。這用於繫結事件,在我們的例子中是 data_received 到在步驟 3 中定義的回撥函式。
  3. 我們定義一個事件驅動函式,該函式表示如果觸發 data_received 事件,則應將文字 data_received 輸出到控制檯。
  4. 最後,我們使用 eventEmiter.emit 函式手動觸發事件。這將觸發 data_received 事件。

程式執行時,文字 data received successfully 將傳送到控制檯。

傳送事件

定義事件時,可以呼叫的事件有不同的方法。本主題重點介紹每個細節。

一次性事件處理程式

有時你可能只對第一次事件做出反應。在這些情況下,你可以使用 once() 方法。

讓我們看看我們如何使用事件處理程式的 once 方法。

var events = require('events');
var eventEmitter = new events.EventEmitter();

eventEmitter.once('data received', function() {
	console.log('data received succesfully.');
});

eventEmitter.emit('data received');

eventEmitter.emit('data received');

程式碼說明: -

  1. 這裡我們使用 once 方法來表示對於 data_received 事件,回撥函式應該只執行一次。
  2. 我們在這裡手動觸發 data_received 事件。
  3. 當再次觸發 data_received 事件時,此時不會發生任何事情。這是因為我們說第一步只能觸發一次事件。

如果程式碼執行正確,則日誌中的輸出將為 data_received successfully。此訊息僅在控制檯中出現一次。

檢查事件偵聽器

在其生命週期的任何時刻,事件發射器可以附加零個或多個偵聽器。可以通過多種方式檢查每種事件型別的偵聽器。

如果你只想確定附加偵聽器的數量,那麼只需檢視 EventEmitter.listenerCount() 方法即可。

注意: Listeners 很重要,因為主程式應該知道是否正在動態新增監聽器,否則程式會因為額外的監聽器被呼叫而出現故障。)

var events = require('events')
var event Emitter = events.EventEmitter,
var emitter = new eventEmitter();

emitter.on('data received', function() {}); emitter.on('data received', function () {});
emitter.on ('data received", function(33; er

console.log(eventEmitter.listenerCount(emitter, "data received"));

程式碼說明: -

  1. 我們正在定義一個 eventEmitter 型別,它是使用與事件相關的方法所必需的。
  2. 然後我們定義一個名為 emitter 的物件,它將用於定義我們的事件處理程式。
  3. 我們正在建立 2 個事件處理程式,基本上什麼都不做。為了展示 listenerCount 方法的工作原理,我們的示例保持簡單。
  4. 現在,當你在 data_received 事件上呼叫 listenerCount 方法時,它將在控制檯日誌中傳送附加到此事件的事件偵聽器數。

如果程式碼執行正確,則 2 將顯示在控制檯日誌中。

newListener Event

每次註冊新的事件處理程式時,事件發射器都會發出 newListener 事件。此事件用於檢測新事件處理程式。當你需要為每個新事件處理程式分配資源或執行某些操作時,通常使用 newListener 事件。

var events = require('events');
var eventEmitter = events.EventEmitter;
var emitter = new eventEmitter();
emitter.on("newListener", function(eventName, listener) {
    console.log("Added listener for " + eventName + " events");
});
emitter.on('data_received', function() {});
emitter.on('data_received', function() {}); 

程式碼說明: -

  1. 我們正在為 newListener 事件建立一個新的事件處理程式。因此,每當註冊新的事件處理程式時,將在控制檯中顯示文字 已新增的偵聽器+事件名稱。
  2. 在這裡,我們正在向控制檯寫入 已新增偵聽器 文字+已註冊的每個事件的事件名稱。
  3. 我們為事件 data_received 定義了 2 個事件處理程式。

如果上面的程式碼執行正確,下面的文字將顯示在控制檯中。它只顯示 newListener 事件處理程式被觸發兩次。

Added listener for data_received events

Added listener for data_received events

摘要

  • 在 Node.js 中使用流來從輸入 - 輸出裝置讀取和寫入資料。Node.js 利用 fs 庫為檔案建立可讀寫的流。這些流可用於從檔案讀取和寫入資料。
  • 管道可用於將多個流連線在一起。最常見的示例之一是將讀取和寫入流一起管道,以便將資料從一個檔案傳輸到另一個檔案。
  • Node.js 通常也被標記為事件驅動框架,並且在 Node.js 中定義事件非常容易。可以定義響應這些事件的函式。
  • 事件還公開了響應關鍵事件的方法。例如,我們已經看到了 once() 事件處理程式,它可以用來確保只在觸發事件時執行一次回撥函式。