不准确"/>
逐行复制大文件不准确
我正在尝试使用 node.js 从大量语料库中正确读取和写入 100 万行。 问题是我得到一个包含一百万行的输出文件,但第 1 百万行是原始文件的第 900 行。
这是我用的:
fs =require("fs");
var buffer = '';
var rs1 = fs.createReadStream('00.jsonl',"ascii");
var ws = fs.createWriteStream('pile_1M.txt', {flags: 'w',encoding: 'ascii'});
var lines_num=0;
var max_read=1000000;
rs1.on('data', function(chunk) {
rs1.pause()
var lines = (buffer+chunk).split(/\r?\n/g);
for (var i = 0; i < lines.length && lines_num<max_read; ++i) {
lines_num++;
ws.write(lines[i]+"\n");}
}
if(lines_num>=max_read){
rs1.close()
console.log("close")
}
rs1.resume();
});
rs1.on('close', function () {
ws.close();
});
回答如下:
你的阅读不一定是整行。它们很可能不会在一行的末尾结束。
所以,你这样做:
var lines = (buffer+chunk).split(/\r?\n/g);
然后,您将这些算作整行,但拆分中的最后一行不一定是整行。
然后你这样做:
ws.write(lines[i]+"\n");
你在每个分割片的末尾添加一个
\n
,但你分割的最后一个可能不是一行的结尾。因此,您最终会在原来没有换行符的地方将块分成新行。
通常的处理方法是保存拆分的最后一块,不要将其算作一行,也不要将其写出。将其保存以添加到下一次阅读中。这样你只写出一个
\n
确实有线边界的地方。
而且,如果行边界是
\r\n
,你也可能有分裂问题,但读取流只读取\r
。然后,您没有正确处理。这个问题也可以通过不处理拆分的最后部分并将其保存以与下一次读取组合来解决。然后,你知道你总是在处理它之前让整行结束。
另外,我看不到您在此代码中的何处重置
buffer
以排除您已经处理和写出的数据。事实上,这段代码似乎从未在 buffer
变量中放置任何行。您应该如前所述使用它来包含最后一部分行。
在一个单独的主题上,您还应该观察流量控制:
ws.write(lines[i]+"\n");
.write()
返回一个布尔值,告诉您缓冲区是否已满,您应该在进一步写入之前等待 drain
事件。这一切都在文档here.中解释
更多推荐
逐行复制大文件不准确
发布评论