如何用Node.js处理大文件(超过1000个文件)的文件目录?

所以,我有一个相当大的文件目录,我需要在NodeJS应用程序中使用长时间运行的进程持续地进行处理。 目录正在不断处理和清空,但在任何给定时间处理1000个文件并不罕见 – 它们是gzip的CSV文件,所以我天真的解决scheme是抓取目录列表,迭代文件,打开每一个,parsing它们,然后继续,如下所示:

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。

有一个更好的方式来处理大量的文件pipe理的方式? 最终,我想使用类似于单个parsingstream的东西 – 我知道如何做到这一点与一个单一的大(甚至增长)的文件,但不是与一个目录充满单独的文件。

这些文件正在由大量不同的客户端生成到面向公众的Web服务器,然后通过安全协议将它们定期同步到我的input目录。 不是一个理想的设置,但是考虑到系统的特定性质,这是必要的,并且解释了为什么我不能简单地改变要说的文件,即单个多路复用stream。

不完全是一个parsingstream,但可能是一个步骤:

您可以使用https://npmjs.org/package/generic-pool来限制正在处理的并发文件数量。 您只需要定义要汇集哪些资源。

在你的情况下,我假设资源池应该是一个文件处理器,以便只有一个或几个可以一次生活。

您也可以使用某种迭代器方法来简化接下来要处理的文件。

编辑:完成我的答案。 我有一个去你的问题,并尝试这个https://gist.github.com/Floby/5064222

Mixu的Node书籍有一个关于如何正确pipe理这类问题的章节。 http://book.mixu.net/node/ch7.html

您可以使用以下代码以“受限并行”的方式运行代码,如下所示 – 并且使用极限参数很容易pipe理您希望一次加载的数量:

 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();