2013-03-01 45 views
2

因此,我有一個相當大的文件目錄,我需要在NodeJS應用程序中使用長時間運行的進程持續進行處理。目錄正在不斷處理和清空,但在任何給定時間處理1000個以上的文件並不罕見 - 它們是gzip壓縮的CSV文件,所以我的天真解決方案是獲取目錄列表,迭代文件,打開每個,解析它們,然後繼續,就像這樣:如何使用Node.js處理大型(超過1000個文件)的文件目錄?

files = fs.readdirSync 'directory' 

for filename in files 
    file_path = path.resolve path.join 'directory', filename 
    fd = fs.openSync file_path, 'r' 
    buf = new Buffer fs.statSync(file_path).size 
    fs.readSync fd, buf, 0, len, 0 
    fs.closeSync fd 
    zlib.gunzip buf, (err, buf) => 
    throw err if err 
    content = buf.toString().split("\n") 
    for line in content 
     # parse, process content, archive file 

我很快針對EMFILE(打開的文件太多)錯誤跑起來。請原諒fs函數的同步版本和coffeescript。

有沒有更好的方式來以管理的方式處理大量的文件?最終,我想使用類似於單個解析流的方式 - 我知道如何使用單個大型文件(甚至是增長文件)來執行此操作,但不能使用單獨文件的目錄。

這些文件由大量不同的客戶端生成到面向公衆的Web服務器,然後通過安全協議將它們定期同步到我的輸入目錄。不是一個理想的設置,但是考慮到系統的特定性質,這是必要的,並且解釋了爲什麼我不能簡單地改變要說的文件,即單個多路複用流。

+0

結帳['graceful-fs'](https://npmjs.org/package/graceful-fs)。 – 2013-03-01 04:03:12

回答

1

不完全解析流,但可能是爭取成爲一個步:

你可以使用https://npmjs.org/package/generic-pool限制正在處理併發的文件數日。您只需定義要彙集的資源。

在你的情況下,我假設池的資源應該是一個文件處理器,以便只有一個或幾個可以一次生活。

您也可以使用某種迭代器方法來簡化接下來要處理的文件。

編輯:完成我的答案。我對你的問題有所瞭解,並嘗試過這樣的嘗試 https://gist.github.com/Floby/5064222

+0

非常好,謝謝。你在這個例子中使用的異步模塊通過實現一個託管併發排隊系統來處理主要問題(我非常喜歡,來自Obj-C和NSOperationQueue)。 – HowlingEverett 2013-03-02 04:40:36

0

Mixu的Node書有一個關於如何正確管理這類問題的章節。 http://book.mixu.net/node/ch7.html

您可以使用下面的代碼運行代碼「有限並聯」,如圖中所示 - 它是易於管理,你希望有多少,一次加載,以極限參數:

function async(arg, callback) { 
    console.log('do something with \''+arg+'\', return 1 sec later'); 
    setTimeout(function() { callback(arg * 2); }, 1000); 
} 
function final() { console.log('Done', results); } 

var items = [ 1, 2, 3, 4, 5, 6 ]; 
var results = []; 
var running = 0; 
var limit = 2; 

function launcher() { 
    while(running < limit && items.length > 0) { 
    var item = items.shift(); 
    async(item, function(result) { 
     results.push(result); 
     running--; 
     if(items.length > 0) { 
     launcher(); 
     } else if(running == 0) { 
     final(); 
     } 
    }); 
    running++; 
    } 
} 

launcher(); 
相關問題