javascript - 在 Node 中高效地逐行读取文件

标签 javascript node.js

我已经知道 readline可用于逐行读取文件,例如

readline
    .createInterface({input: fs.createReadStream('xxx')})
    .on('line', (line) => { apply_regexp_on_line })
    .on('close', () => { report_all_regexps });

但是,这很慢,因为我比较了 grep 和 JavaScript 正则表达式的性能,后者在我测试的正则表达式上具有更好的性能。 (见 benchmark )所以我认为我不得不责怪 Node 异步读取线。

在我的情况下,我根本不关心异步,我只需要利用 JavaScript 的快速正则表达式来处理非常大的日志文件(通常为 1-2GB,有时高达 10GB)。这样做的最佳方法是什么?我唯一关心的是速度。

加分项:一些日志文件是 gzip 压缩的,所以我需要解压缩它们。如果有人可以推荐我一个快速的逐行阅读器,可以同时读取纯文本和压缩文本,我将不胜感激。

最佳答案

这对您的数据有何影响?

// module linegrep.js
'use strict';
var through2 = require('through2');
var StringDecoder = require('string_decoder').StringDecoder

function grep(regex) {
    var decoder = new StringDecoder('utf8'),
        last = "",
        lineEnd = /\r?\n/;

    var stream = through2({}, function transform(chunk, enc, cb) {
        var lines = decoder.write(last + chunk).split(lineEnd), i;
        last = lines.pop();
        for (i = 0; i < lines.length; i++) {
            if (regex.test(lines[i])) this.push(lines[i]);
        }
        cb();
    }, function flush(cb) {
        if (regex.test(last)) this.push(last);
        cb();
    });
    stream._readableState.objectMode = true;
    return stream;
}

module.exports = grep;

// index.js

'use strict';
var fs = require('fs');
var zlib = require('zlib');
var grep = require('./linegrep');

function grepFile(filename, regex) {
    var rstream = fs.createReadStream(filename, {highWaterMark: 172 * 1024});
    if (/\.gz$/.test(filename)) rstream = rstream.pipe(zlib.createGunzip());
    return rstream
        .pipe(grep(regex));
}

// -------------------------------------------------------------------------

var t = Date.now(), mc = 0;
grepFile('input.txt', /boot\.([a-z]+)_head\./).on('data', function (line) {
    mc++;
    console.log(line);
}).on('end', function () {
    console.log( mc + " matches, " + (Date.now() - t) + " ms" );
});

这会将文件流转换为行的对象流,通过您的正则表达式映射它们并仅返回匹配的行。

关于javascript - 在 Node 中高效地逐行读取文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38091565/

相关文章:

javascript - 将切换按钮替换为复选框但不起作用

javascript - Window.onbeforeunload - 了解用户点击了什么 Angular 5

javascript - Node.js 和 Actionscript (as3crypto) 之间的 AES 损坏

javascript - 为什么错误处理在 nodemailer 中不起作用?

javascript - 任何基于 JavaScript/jQuery 的 html 数据处理器/美化器?

javascript - 从嵌套 JSON 中获取值

javascript - D3 图表示例 "TypeError: data is undefined"

javascript - 带有 jQ​​uery 的 fancybox v2

javascript - 如何在 Google Dialogflow Fullfilment 内联编辑器中安装 npm 包

node.js - 亚马逊 AWS Lambda NodeJS 日志记录