我有一个包含大量条目(1000多万个)的文件,每个条目代表一个部分文档,该文档被保存到mongo数据库中(基于某些标准,非常重要)。
为避免数据库过载(同时进行其他操作),我希望读取X行的块,等待它们完成,读取下一行X行等。
有没有办法使用任何fs
回调机制在某个时刻“停止”进度,而不会阻止整个程序?从我所知道的,除非你完全停止阅读文件,否则它们将从头到尾全部运行而无法停止它。
问题在于,由于文件大小,内存也成为问题,并且由于更新所花费的时间,大量数据将被保存在超过1 GB限制的内存中并导致程序崩溃。其次,正如我所说,我不想排队100万次更新并完全强调mongo数据库。
欢迎提出任何建议。
更新:使用line-reader
(可通过npm获取)的最终解决方案,使用伪代码。
var lineReader = require('line-reader');
var filename = <wherever you get it from>;
lineReader(filename, function(line, last, cb) {
//
// Do work here, line contains the line data
// last is true if it's the last line in the file
//
function checkProcessed(callback) {
if (doneProcessing()) { // Implement doneProcessing to check whether whatever you are doing is done
callback();
}
else {
setTimeout(function() { checkProcessed(callback) }, 100); // Adjust timeout according to expecting time to process one line
}
}
checkProcessed(cb);
});
这是为了确保doneProcessing()在尝试处理更多行之前返回true来实现 - 这意味着你可以有效地限制你正在做的事情。
答案 0 :(得分:2)
我不使用MongoDB而且我不是使用Lazy的专家,但我认为下面的内容可能会起作用或给你一些想法。 (请注意,我还没有测试过此代码)
var fs = require('fs'),
lazy = require('lazy');
var readStream = fs.createReadStream('yourfile.txt');
var file = lazy(readStream)
.lines // ask to read stream line by line
.take(100) // and read 100 lines at a time.
.join(function(onehundredlines){
readStream.pause(); // pause reading the stream
writeToMongoDB(onehundredLines, function(err){
// error checking goes here
// resume the stream 1 second after MongoDB finishes saving.
setTimeout(readStream.resume, 1000);
});
});
}