1

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

这些文件每天晚上都被抓住,我需要阅读这些文件而不必将它们解压缩到磁盘。

据我了解,我可以使用 zlib 将文件解压缩为某种形式的流,但我不知道如何获取数据,也不知道如何一次轻松地处理一行(尽管我知道某种将涉及到循环搜索 \n。

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

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

1 回答 1

1

你应该看看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.
})

我希望这会有所帮助

于 2014-05-18T08:00:08.847 回答