在Node.js中逐行讀取文件【純技術】

  • 2019 年 10 月 6 日
  • 筆記

介紹

在計算機科學中,文件是一種資源,用於在計算機的存儲設備中離散地記錄數據。Node.js不會以任何方式覆蓋它,並且可以與文件系統中被視為文件的任何文件一起使用。

讀取文件和資源有許多用途:

  • 統計,分析和報告
  • 機器學習
  • 處理大型文本文件或日誌

有時,這些文件可能非常大,存儲了千兆位元組或TB級的文件,而整個文件的讀取效率很低。

能夠逐行讀取文件使我們能夠僅查找相關信息,並在找到所需內容後停止搜索。它還使我們可以將數據分解為邏輯片段,就像文件是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 的開源行讀取器模塊來查看它的較短版本。

由於它是一個非本地模塊,因此我們需要確保已使用正確的方式初始化了npm項目npm init,然後進行安裝:

$ npm install --save line-reader

這將安裝依賴項並將其添加到package.json文件中。

完成後,逐行讀取文件僅與前面的示例相似,而無需readInterface在中間創建文件:

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中有多種方式逐行讀取文件,選擇適當的方法完全是程序員的決定。

您應該考慮計劃要處理的文件的大小,性能要求,代碼樣式以及項目中已經存在的模塊。確保在一些極端情況下進行測試,例如巨大,空白或不存在的文件,並且最好使用提供的任何示例。