2016-07-04 82 views
0

我需要監視文件的更改。由於這個文件有大量的新條目,我需要'監視'這個文件。我需要獲取新插入的內容到這個文件才能解析這個內容。Node.js監視文件的更改並解析它們

我發現這個代碼:

fs.watchFile('var/log/query.log', function() { 
console.log('File Changed ...'); 
//how to get the new line which is now inserted? 
}); 
+0

我不知道怎麼去只有這對於例如當文件發生了改變的內容插入到插入內容行的數組。 –

回答

1

在bash,那麼你會做這樣的事情與tail --follow

還有一個包tail availible。 你可以看一個文件,並與事件得到新線:

const Tail = require('tail').Tail; 
var tail = new Tail("var/log/query.log"); 
tail.watch() 
tail.on("line", data => { 
    console.log(data); 
}); 
+0

這似乎是最好的方法,但是當我測試這個並在文件頂部添加一個換行符時,它會將新行解析爲空行?! –

+0

如果只向該文件添加換行符,它將返回一個空字符串,因爲對於每個新行,事件被觸發(換行符被刪除)。如果你想一次解析多行,你必須自己重建字符串 – Julian

0

下面是我如何使用fs.watchFile監視一個叫爐石遊戲中的日誌文件,並拿起新的日誌條目來監視的例子他們在比賽中發生的比賽事件。 https://github.com/chevex-archived/hearthstone-log-watcher/blob/master/index.js

var fs = require('fs'); 
var options = { 
    logFile: '~/Library/Preferences/Blizzard/Hearthstone/log.config', 
    endOfLineChar: require('os').EOL 
}; 
// Obtain the initial size of the log file before we begin watching it. 
var fileSize = fs.statSync(options.logFile).size; 
fs.watchFile(options.logFile, function (current, previous) { 
    // Check if file modified time is less than last time. 
    // If so, nothing changed so don't bother parsing. 
    if (current.mtime <= previous.mtime) { return; } 

    // We're only going to read the portion of the file that 
    // we have not read so far. Obtain new file size. 
    var newFileSize = fs.statSync(options.logFile).size; 
    // Calculate size difference. 
    var sizeDiff = newFileSize - fileSize; 
    // If less than zero then Hearthstone truncated its log file 
    // since we last read it in order to save space. 
    // Set fileSize to zero and set the size difference to the current 
    // size of the file. 
    if (sizeDiff < 0) { 
    fileSize = 0; 
    sizeDiff = newFileSize; 
    } 
    // Create a buffer to hold only the data we intend to read. 
    var buffer = new Buffer(sizeDiff); 
    // Obtain reference to the file's descriptor. 
    var fileDescriptor = fs.openSync(options.logFile, 'r'); 
    // Synchronously read from the file starting from where we read 
    // to last time and store data in our buffer. 
    fs.readSync(fileDescriptor, buffer, 0, sizeDiff, fileSize); 
    fs.closeSync(fileDescriptor); // close the file 
    // Set old file size to the new size for next read. 
    fileSize = newFileSize; 

    // Parse the line(s) in the buffer. 
    parseBuffer(buffer); 
}); 

function stop() { 
    fs.unwatchFile(options.logFile); 
}; 

function parseBuffer (buffer) { 
    // Iterate over each line in the buffer. 
    buffer.toString().split(options.endOfLineChar).forEach(function (line) { 
    // Do stuff with the line :) 
    }); 
}; 

它首先計算,因爲此日誌觀察者模塊我只希望,因爲它是由遊戲寫成的新數據文件的初始大小。我不在乎現有的數據。然後它開始觀看文件以進行更改。當更改處理程序觸發時,我們檢查修改的時間是否真的更新,因爲當沒有我們關心的數據實際發生更改時,有關文件的其他更改可能觸發處理程序。我們希望這位守望者能夠儘可能保持高性能。

然後我們讀取文件的新大小並計算出上次的差異。這告訴我們究竟要從文件中讀取多少數據才能獲得新寫入的數據。然後,我們將數據存儲在緩衝區中,並將其解析爲字符串。只需用換行符分割字符串即可。使用核心模塊os得到os.EOL將爲您提供正在運行的操作系統的正確行結束字符(windows行結束字符與linux/unix不同)。

現在你已經寫入文件: