2015-10-12 70 views
0

我正在閱讀一些文件(每個文件約爲2MB)。在nodejs中讀取大量文件

起初我想:

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 

因此,我的想法是讀取卡盤的文件。我的意思是:開始閱讀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"); 

我應該如何讓for循環暫停,直到ReadFile函數做?

回答

0

你可以做的是使用承諾,我特別喜歡bluebird因爲它有一些非常方便的功能。

使用藍鳥,您可以爲.map()函數提供concurrency參數,以限制一次讀取的文件數量。而不是等待10個文件來完成,然後分塊另一個10,它只是確保不超過10個文件simulataneously閱讀:

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! 
});
+0

還挺內存用完:P – user1640736

+0

@ user1640736我有一個類似的結構超過100,000個文件,而且我沒有耗盡內存。你在運行什麼版本的節點,以及在哪個服務器上運行? –

+0

似乎不是內存問題,也發生在1個文件中:http://paste.isomorphis.me/W0n – user1640736