2

そのため、NodeJS アプリケーションで実行時間の長いプロセスを使用して継続的に処理する必要があるファイルのかなり大きなディレクトリがあります。ディレクトリは継続的に処理され、空にされていますが、常に 1000 以上のファイルが処理のために並んでいることは珍しくありません - それらは gzip された CSV ファイルであるため、私の単純な解決策は、ディレクトリ リストを取得し、ファイルを反復処理することでした。 、それぞれを開いて解析し、次のように続行します。

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 (Too Many Open Files) エラーがすぐに発生します。fs 関数の Sync バージョンと、coffeescript についてはご容赦ください。

管理された方法で大量のファイルを処理するより良い方法はありますか? 最終的には、単一の解析ストリームのようなものを使用したいと思います-単一の大きな(または成長している)ファイルでそれを行う方法は知っていますが、個別のファイルでいっぱいのディレクトリではできません。

ファイルは、多数の異なるクライアントによって公開 Web サーバーに生成され、安全なプロトコルを介して入力ディレクトリに定期的に同期されます。理想的なセットアップではありませんが、システムの特定の性質を考えると必要であり、単一の多重化されたストリームなど、ファイルを単純に変更できない理由を説明しています。

4

2 に答える 2

1

正確には解析ストリームではありませんが、それに向けた一歩になる可能性があります:

https://npmjs.org/package/generic-poolを使用して、処理される同時ファイルの数を制限できます。プールするリソースを定義するだけです。

あなたの場合、プールするリソースはファイル プロセッサである必要があると想定しているため、一度に 1 つまたは少数しか存在できません。

次に処理するファイルを合理化するために、ある種の反復子メソッドを使用することもできます。

編集:私の答えを完成させます。私はあなたの問題を試して、これを試しました https://gist.github.com/Floby/5064222

于 2013-03-01T10:34:19.560 に答える
0

Mixu の Node book には、この種の問題を正確に管理する方法に関するセクションがあります。http://book.mixu.net/node/ch7.html

そこに示されているように、次のコードを使用して「制限された並列」でコードを実行できます。また、 limit パラメータを使用して、一度にロードする数を簡単に管理できます。

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();
于 2014-02-19T05:05:44.960 に答える