2013-07-02 35 views
1

我正在使用節點處理應用程序中的日誌文件,並且由於流量的大小,每天大小可能會超過千兆字節。如何解析節點中的大型分隔文本文件

這些文件是每晚都抓住的,我需要讀取這些文件而不必將它們解壓縮到磁盤。

從我的理解我可以使用zlib解壓縮文件到某種形式的流,但我不知道如何獲取數據,不知道我怎麼可以然後輕鬆地處理一條線(雖然我知道某種while循環搜索\ n將被涉及。

最接近的答案,我發現到目前爲止是演示如何管流SAX解析器,但整個節點管/流是有點混亂

fs.createReadStream('large.xml.gz').pipe(zlib.createUnzip()).pipe(saxStream); 
+0

你有沒有考慮寫一個原生擴展,並使用C++庫?如果你的文件很大,這可能是最好的選擇...... – ChrisCM

+0

不知道C++ tbh。目前我可以通過解壓文件然後使用最後期限來完成,但是當我將其轉入生產環境時,權限被鎖定,因此我無法更改日誌文件夾的內容,只能從中讀取。 –

+0

嘗試使用sudo執行您的節點進程? – ChrisCM

回答

0

你應該看看sax。 它是由isaacs開發的!

我還沒有測試過這段代碼,但是我會先寫這些代碼。

var Promise = Promise || require('es6-promise').Promise 
, thr = require('through2') 
, createReadStream = require('fs').createReadStream 
, createUnzip = require('zlib').createUnzip 
, createParser = require('sax').createStream 
; 

function processXml (filename) { 
    return new Promise(function(resolve, reject){ 
    var unzip = createUnzip() 
    , xmlParser = createParser() 
    ; 

    xmlParser.on('opentag', function(node){ 
     // do stuff with the node 
    }) 
    xmlParser.on('attribute', function(node){ 
     // do more stuff with attr 
    }) 

    // instead of rejecting, you may handle the error instead. 
    xmlParser.on('error', reject) 
    xmlParser.on('end', resolve) 

    createReadStream(filename) 
    .pipe(unzip) 
    .pipe(xmlParser) 
    .pipe(thr(function(chunk, enc, next){ 
     // as soon xmlParser is done with a node, it passes down stream. 
     // change the chunk if you wish 
     next(null, newerChunk) 
    })) 

    rl = readline.createInterface({ 
     input: unzip 
    , ouput: xmlParser 
    }) 
    }) 
} 

processXml('large.xml.gz').then(function(){ 
    console.log('done') 
}) 
.catch(function(err){ 
    // handle error. 
}) 

我希望幫助