读取X行数的段中的文件

时间:2013-05-07 07:59:22

标签: node.js file-io

我有一个包含大量条目(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来实现 - 这意味着你可以有效地限制你正在做的事情。

1 个答案:

答案 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); 
      });
  });
}