如何解析节点中的大分隔文本文件

时间:2013-07-02 18:29:37

标签: node.js logging stream gzip pipe

我正在使用Node来处理来自应用程序的日志文件,并且由于流量大小,每天的大小可能是一个千兆字节左右。

每晚都会抓住文件,我需要读取文件而不必将它们解压缩到磁盘。

根据我的理解,我可以使用zlib将文件解压缩到某种形式的流但我不知道如何获取数据并且不确定我如何能够轻松地一次处理一行(虽然我知道将涉及某种类型的while循环搜索\ n。

我到目前为止找到的最接近的答案是演示如何将流传输到sax解析器,但整个节点管道/流有点混乱

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

1 个答案:

答案 0 :(得分: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.
})

我希望有帮助