Node.js 小密技:以 Readline 核心模組一行行讀取檔案內容


最近參與了一些關於資料處理的專案,處理了很多各式各樣的原始資料(Raw Data)或各種不同格式的資料,於是使用到了 Node.js 上的一些小技巧。像是一行行讀取檔案內容這件事,就隱藏了一些技巧。

對很多人來說,處理的檔案內容都不大,如果用 Node.js 來一行行讀取檔案內容,不外乎就是將整個檔案讀出後再進行切割,做法大致上如下:
var fs = require('fs');

fs.readFile('example.txt', function(err, data) {

    // 以換行字元作為切割點,將內容切成一個大陣列
    var lines = data.split('\n');

    lines.forEach(function(line) {
        // 一行行處理
    });
});
但有些時候,由於檔案並不小,若又牽涉到運算,不可能整個檔案都讀出到記憶體上才進行切割,這時就得用到 Stream(資料流)機制,將檔案一段段讀出來進行處理。然後,為了進行一行行的切割,我們會自己做這樣的機制,先將一段段讀取出來的檔案內容放到緩衝區(Buffer),然後找到換行字元進行切斷取出,然後再繼續讀取檔案,重複這樣的過程直到檔案結尾。

的確,實做這樣的機制有點麻煩,所以其實能利用 Node.js 現成內建的核心模組 Readline 來做到切割資料流中一行字串的工作。因為常見的 Readline 用法都是拿來做終端機字元模式下的命令列操作,所以許多人沒有想到可以這樣使用 Readline。作法其實很簡單,就把 Readline 的 input 從標準輸入(Standard Input)換成我們的檔案讀取資料流就可以。

完整做法如下:
var fs = require('fs');
var readline = require('readline');

// 建立檔案讀取資料流
var inputStream = fs.createReadStream('example.txt');

// 將讀取資料流導入 Readline 進行處理 
var lineReader = readline.createInterface({ input: inputStream });
lineReader.on('line', function(line) {

    // 取得一行行結果
    console.log('NEW LINE', line);
});

後記

其實這樣的 Readline 用法,在 Node.js 官方 API 文件上可以看到,只不過是不久前才被加進去的,在文件的最後面。:-P

參考連結:https://nodejs.org/api/readline.html

這個網誌中的熱門文章

Web 技術中的 Session 是什麼?

NodeJS 與 MongoDB 的邂逅

淺談 USB 通訊架構之定義(一)

淺談 USB 通訊架構之定義(二)

JavaScript 好用的 async 異步函數!