我有一个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.
});
};
答案 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();
}