在Node.JS中一次读取一行大文件N行

时间:2017-07-22 22:57:12

标签: javascript arrays node.js

我有一个65,000,000行的文件,大小约为2GB。

我想一次读取N行中的这个文件,执行数据库插入操作,然后读取下一个N,在这种情况下N为1000。插入顺序无关紧要,因此同步很好。

这样做的最佳方法是什么?我只发现要么一次加载1行,要么将整个文件读入内存的方法。下面的示例代码,我一直用来一行读取一行文件。 :

var singleFileParser = (file, insertIntoDB) => {
    var lr = new LineByLineReader(file);
    lr.on('error', function(err) {
        // 'err' contains error object
        console.error(err);
        console.error("Error reading file!");
    });

    lr.on('line', function(line) {
        insertIntoDB(line);
    // 'line' contains the current line without the trailing newline character.
    });

    lr.on('end', function() {
        // All lines are read, file is closed now.
    });
};

3 个答案:

答案 0 :(得分:1)

这样的事情应该做

var cnt = 0;
var tenLines = [];
lr.on('line', function(line) {
    tenLines.push(line);
    if (++cnt >= 10) {
         lr.pause();
         // prepare your SQL statements from tenLines
         dbInsert(<yourSQL>, function(error, returnVal){
            cnt = 0;
            tenLines = [];
            lr.resume();
        });
     }
});

答案 1 :(得分:1)

某些人只能一次解析一行。所以,如果你想要一次10个,那么你只需要一次收集一个,直到你收集了10个,然后处理10个。

我不认为Jarek的代码工作正常,所以这里有一个不同的版本,它将10行收集到一个数组中,然后调用dbInsert()

var tenLines = [];
lr.on('line', function(line) {
    tenLines.push(line);
    if (tenLines.length === 10) {
        lr.pause();
        dbInsert(<yourSQL>, function(error, returnVal){
            if (error) {
                // some sort of error handling here
            }
            tenLines = [];
            lr.resume();
        });
     }
});
// process last set of lines in the tenLines buffer (if any)
lr.on('end', function() {
    if (tenLines.length !== 0) {
        // process last set of lines
        dbInsert(...);
    }
});

Jarek的版本似乎在每个dbInsert()事件上调用line而不是仅在每个第10行事件中调用SELECT spechist.item,image."image-path",image."image-item",image."image-source" FROM PUB.spechist left outer join PUB.image on (image."image-item"=spechist.item) WHERE (spechist."photocard-display"=yes) AND (spechist."rec-type"='I') and (spechist.item='111') 并且如果它们不是&#,则不会处理文件末尾的任何剩余行39; ta长10行的完美倍数。

答案 2 :(得分:0)

这是我在异步函数中的解决方案:

let multipleLines = [];
const filepath = '<file>';
const numberLines = 50;

const lineReader = require('readline').createInterface({
    input: require('fs').createReadStream(filepath)
});

// process lines by numberLines
for await (const line of lineReader) {
    multipleLines.push(line);
    if (multipleLines.length === numberLines) {
        await dbInsert();
        multipleLines = [];
    }
}
// process last set of lines (if any)
if (multipleLines.length !== 0) {
    await dbInsert();
}