Node.js 以X行数的段读取文件

Node.js 以X行数的段读取文件,node.js,file-io,Node.js,File Io,我有一个包含大量条目(1000多万条)的文件,每个条目代表一个正在保存到mongo数据库的部分文档(基于一些标准,非常重要) 为了避免数据库过载(同时执行其他操作),我希望读取大量的X行,等待它们完成,读取下一个X行,等等 是否有任何方法可以使用任何fs回调机制在某一点“暂停”进程,而不阻塞整个程序?据我所知,除非您完全停止读取文件,否则它们将从头到尾运行,无法停止 问题在于,由于文件大小的原因,内存也成为一个问题,而且由于更新所需的时间,大量数据将保存在内存中,超过1GB限制,导致程序崩溃。其

我有一个包含大量条目(1000多万条)的文件,每个条目代表一个正在保存到mongo数据库的部分文档(基于一些标准,非常重要)

为了避免数据库过载(同时执行其他操作),我希望读取大量的X行,等待它们完成,读取下一个X行,等等

是否有任何方法可以使用任何
fs
回调机制在某一点“暂停”进程,而不阻塞整个程序?据我所知,除非您完全停止读取文件,否则它们将从头到尾运行,无法停止

问题在于,由于文件大小的原因,内存也成为一个问题,而且由于更新所需的时间,大量数据将保存在内存中,超过1GB限制,导致程序崩溃。其次,正如我所说的,我不想排队等待100万次更新,而完全强调mongo数据库

欢迎提出任何建议

更新:使用以下伪代码中的
行读取器
(可通过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);
});
var lineReader=require('line-reader');
var文件名=;
lineReader(文件名、函数(行、最后一行、cb){
//
//在这里工作,行包含行数据
//如果是文件中的最后一行,则last为true
//
函数checkProcessed(回调){
if(doneProcessing()){//实现doneProcessing以检查您正在做的事情是否完成
回调();
}
否则{
setTimeout(function(){checkProcessed(callback)},100);//根据处理一行的预期时间调整超时
}
}
检查处理(cb);
});

这是为了确保doneProcessing()在尝试处理更多行之前返回true,这意味着您可以有效地限制您正在做的任何事情。

我不使用MongoDB,我也不是使用MongoDB的专家,但我认为下面类似的方法可能会起作用或给您一些想法。(请注意,我尚未测试此代码)


take(100)不是一次取100行,而是取100行并在链中传递。我尝试过使用take(X)进行查看,但这在事件发射器上达到了一个极限,无法工作。readStream.pause()是否对解决此问题没有帮助?我把它放在那里,否则你的整个流将被一次读取而不会停止,最终你将被调用成吨的函数(onehundledlines)。以某种方式暂停流是至关重要的。readStream.pause()和resume()使流完全停止,而不再继续。最后我使用了
行阅读器
,这是一种更直接的方式,允许更细粒度的控制。可惜暂停和恢复没有起作用。我觉得代码看起来很整洁:)我想知道这是Lazy的bug还是readstream本身。您使用的是Node的哪个版本?它是较旧的版本,因此可能与此相关。我仍然觉得
line reader
当您想要限制和精确地访问数据的使用速度时,如果您想要在速度/限制不是问题的情况下易于实现,那么
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); 
      });
  });
}