2013-07-02 36 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. 
}) 

我希望帮助