我正在流传输两个无法容纳在内存中的大文件,我需要逐行比较这两个文件,并应用需要积累一些信息的比较功能。
假设我有两个流:const stream1, stream2
。而我需要积累一些结果。举个例子,假设这是两个文件中let count
中相同位置的行数的计数。
这是我尝试的方法:
const stream1 = getLineByLineReadable1Somehow(), stream2 = getLineByLineReadable2Somehow();
let count = 0;
stream1.on('readable', () => {
stream2.on('readble', () => {
let line1, line2;
while (line1 = stream1.read()) {
line2 = stream2.read();
if (line1 !== line2) count++;
}
});
});
console.log(count);
只要两个文件很小,此方法就可以正常工作,但是当文件变大时,它们会完全崩溃。最后提供的计数不正确。不确定发生了什么,但我认为这与两个流之一被多次触发的readable
事件有关。在某些时候,两个流之一只是吐出一堆null
一会儿。
在此问题上的帮助将不胜感激。谢谢!
答案 0 :(得分:0)
问题在于,在大文件上,新行到达的事件可能非常不规则。因此,必须有一个中间缓冲区。这是一个有效的代码段:
var readline = require('readline');
var fs = require('fs');
var rs1 = fs.createReadStream('1.log');
var r1 = readline.createInterface({
input: rs1
});
var rs2 = fs.createReadStream('2.log');
var r2 = readline.createInterface({
input: rs2
});
var stats = {
count: [0, 0],
common: 0,
closed: 0,
lines: [
[],
[]
]
}
function compare(line, i) {
stats.count[i]++;
if (stats.closed === 0 || stats.lines[1 - i].length > 0) stats.lines[i].push(line);
while (stats.lines[0].length > 0 && stats.lines[1].length > 0) {
var L1 = stats.lines[0].shift();
var L2 = stats.lines[1].shift();
if (L1 === L2) stats.common++;
}
}
function close() {
if (++stats.closed === 2) console.log(stats.count, stats.common, stats.lines[0].length, stats.lines[1].length);
}
r1.on('line', (line) => compare(line, 0))
r2.on('line', (line) => compare(line, 1))
r1.on('close', close);
r2.on('close', close);