在nodejs中读取大量文件

时间:2015-10-12 11:50:13

标签: node.js

我正在寻找一些文件(每个文件大约2MB)。

起初我试过了:

    for (var j = 0; j <= limit2; ++j)
    fs.readFile(base + i * j + last, {encoding: "utf-8"}, function (err, data) {
        cnt++;
        if (cnt == limit2)
            console.timeEnd("random");
    });

这做得很好,但看起来阅读时间不是永远的liniar:

30 files : ~8s
300 files : ~ 12s
600 files : ~ 22s
1000 files : ~ 120s

因此,我的想法是用chucks读取那些文件。我的意思是:开始读取10个文件,等待所有文件完成,然后继续下一个10个文件,等等。

我尝试过类似的事情:

function ReadFiles() {
for (var j = 0; j <= limit2; ++j)
    fs.readFile(base + i * j + last, {encoding: "utf-8"}, function (err, data) {
        cnt++;
        if (cnt == limit2)
           // console.timeEnd("random");
    });
}

for (var i = 0; i <= limit1; ++i) {
GoOn = false;
cnt = 0;
ReadFiles();
}
console.timeEnd("random");

在ReadFile函数完成之前,我应该如何使for循环暂停?

2 个答案:

答案 0 :(得分:0)

您可以尝试使用异步模块。 对于这个用例,它有一个特殊的.queue方法: https://github.com/caolan/async#queue

否则你自己实现它不应该那么复杂。

答案 1 :(得分:0)

你可以做的是使用Promises,我特别喜欢 bluebird ,因为它有一些非常方便的功能。

使用bluebird,您可以向concurrency函数提供.map()参数,以限制一次读取的文件数。而不是等待10个文件完成,然后再分块10,它只会确保同时读取不超过10个文件:

var Promise = require('bluebird');
var fs = require('fs');

// Creates a promise returning function from a callback-based function
var readFileAsync = Promise.promisify(fs.readFile);

// Add all filenames into an array
var files = [];
for (var i = 0; i <= limit1; i++) {
    for (var j = 0; i <= limit2; j++) {
        files.push(base + i*j + last); 
    }
}

var allDonePromise = Promise.map(files, function(file) {
    return readFileAsync(file, {encoding: "utf-8"});
}, { concurrency: 10 }); // Magic is here!
allDonePromise.then(function(allFileContents) {
    // Here, we're all done!
});