在 Node.js 中逐行讀取文件
簡介
在計算機科學中,文件是用於在計算機存儲設備中離散地記錄數據的資源。 Node.js 不會以任何方式覆蓋它,它適用於文件系統中被視為文件的任何內容。
讀取文件和資源有很多用途:
- 統計、分析和報告
- 機器學習
- 處理大型文本文件或日誌
有時,這些文件可能大得離譜,存儲了千兆字節或兆兆字節,並且完整地讀取它們是低效的。
能夠逐行讀取文件使我們能夠僅查找相關信息並在找到所需內容後停止搜索。它還允許我們將數據分解成邏輯片段,就像文件是 CSV 格式一樣。
Readline(從 v0.12 及更高版本)
Node.js 具有讀取文件的本機模塊,允許我們逐行讀取。它是在 2015 年添加的,旨在從任何 Readable
中讀取 一次播放一行。
這個事實使它成為一個通用的選項,不僅適用於文件,甚至像 process.stdin
這樣的命令行輸入 . readline
上的文檔 模塊可以在這裡找到。
作為 readline
是一個原生模塊。您不必使用 npm
到任何其他包管理器來添加它,只需 require
:
const readline = require('readline');
一切順利!
作為 readline
方法應該提供一個流,我們必須首先使用另一個原生模塊 - fs
創建它 :
const fs = require('fs');
下一步是創建將使用 createInterface()
從流中讀取的對象 功能:
const readInterface = readline.createInterface({
input: fs.createReadStream('/path/to/file'),
output: process.stdout,
console: false
});
確保替換為 /path/to/file
文件系統中文件的實際路徑。
準備工作完成後,可以通過以下方式逐行讀取文件並將其內容打印到控制台:
readInterface.on('line', function(line) {
console.log(line);
});
在這裡,我們本質上是說,只要 line
事件發生在 readInterface
它應該調用我們的函數並將從流中讀取的內容傳遞給它。在我們的例子中,我們不想讓事情變得過於復雜,而只是將其打印到控制台。
行閱讀器
在詳細解釋瞭如何使用原生 Node.js 模塊逐行讀取文件之後,讓我們看一下使用 npm 的開源 line-reader 模塊的較短版本。
由於它是一個非本地模塊,我們需要確保我們已經使用 npm init
以正確的方式初始化了 npm 項目 然後安裝它:
$ npm install --save line-reader
這將安裝依賴項並將其添加到 package.json
文件。
完成後,逐行讀取文件與前面的示例類似,只是無需創建 readInterface
中間:
免費電子書:Git Essentials
查看我們的 Git 學習實踐指南,其中包含最佳實踐、行業認可的標準以及隨附的備忘單。停止谷歌搜索 Git 命令並真正學習 它!
const lineReader = require('line-reader');
lineReader.eachLine('/path/to/file', function(line) {
console.log(line);
});
這裡一個非常有用的功能是在某些條件變為真時停止閱讀。這可以通過簡單地返回 false
來實現 來自回調函數。
例如,我們可以逐行讀取文件,直到找到包含“STOP”字樣的行:
lineReader.eachLine('path/to/file', function(line) {
console.log(line);
if (line.includes('STOP') {
return false; // stop reading
}
});
有一種稍微不同的方法,它使用兩個嵌套的回調和語法,這對 Java 開發人員來說可能看起來更自然:
lineReader.open('/path/to/file', function(reader) {
if (reader.hasNextLine()) {
reader.nextLine(function(line) {
console.log(line);
});
}
});
在這裡,我們使用 open()
函數,它不會立即為我們提供文件中的行,而是給我們一個 reader
.它有自己的一組函數,例如 hasNextLine()
和 nextLine()
這讓我們可以更好地控制在 Node.js 中逐行讀取文件的過程。
N-readlines
npm 模塊 n-readlines
提供了不同的語法 :
讓我們安裝它:
$ npm install --save n-readlines
並要求它:
const lineByLine = require('n-readlines');
為了能夠從文件中讀取,我們應該創建一個新對象,並提供我們文件的路徑作為參數:
const liner = new lineByLine('/path/to/file');
通過調用 next
從文件中獲取行 功能:
let line;
while (line = liner.next()) {
console.log(line);
}
n-readlines
的一個有趣功能 模塊是 reset()
.它重置指針並從文件的最開頭開始讀取過程。
注意 :只有在沒有到達終點時才有效。
常見錯誤
在 Node.js 中逐行讀取文件時的一個常見錯誤是將整個文件讀入內存,然後通過換行符分割其內容。
這是一個不正確的 如果您提供足夠大的文件,可能會使系統過載的示例:
require('fs').readFileSync('/path/to/file', 'utf-8').split(/\r?\n/).forEach(function(line) {
console.log(line);
});
乍一看,這種方法的輸出似乎與以前的方法相同,實際上,它對於小文件也適用。但是繼續嘗試與大的一起工作。這絕對不是您希望在生產系統中看到的東西。
結論
Node.js中有多種逐行讀取文件的方式,選擇合適的方式完全是程序員的決定。
您應該考慮計劃處理的文件的大小、性能要求、代碼風格和項目中已經存在的模塊。確保在一些極端情況下進行測試,例如巨大的、空的或不存在的文件,你會很好地使用提供的任何示例。