レコードIDの巨大な(> 1GB)CSVがあるとします。
655453
4930285
493029
4930301
493031
...
そして、それぞれについてid
、REST API呼び出しを行って、レコードデータをフェッチし、ローカルで変換して、ローカルデータベースに挿入します。
Node.jsのReadableStream
でそれをどのように行いますか?
私の質問は基本的にこれです:どのようにして非常に大きなファイルを行ごとに読み取り、各行に対して非同期関数を実行し、[オプションで]特定の行からファイルの読み取りを開始できるようにしますか?
次のQuoraの質問から、私は使い方を学び始めていますfs.createReadStream
:
http://www.quora.com/What-is-the-best-way-to-read-a-file-line-by-line-in-node-js
var fs = require('fs');
var lazy = require('lazy');
var stream = fs.createReadStream(path, {
flags: 'r',
encoding: 'utf-8'
});
new lazy(stream).lines.forEach(function(line) {
var id = line.toString();
// pause stream
stream.pause();
// make async API call...
makeAPICall(id, function() {
// then resume to process next id
stream.resume();
});
});
lazy
ただし、モジュールはファイル全体を(ストリームとして、ただし一時停止はありません)読み取るように強制するため、その擬似コードは機能しません。そのため、そのアプローチはうまくいかないようです。
もう1つは、特定の行からこのファイルの処理を開始できるようにしたいということです。これは、各処理id
(API呼び出しの実行、データのクリーニングなど)がレコードごとに最大0.5秒かかる可能性があるため、毎回ファイルの先頭から開始する必要がないためです。私が使用することを考えている素朴なアプローチは、最後に処理されたIDの行番号をキャプチャして、それを保存することです。次に、ファイルを再度解析するときに、中断した行番号が見つかるまで、すべてのIDを1行ずつストリーミングしてから、makeAPICall
ビジネスを実行します。もう1つの単純なアプローチは、小さなファイル(たとえば、100個のID)を作成し、各ファイルを一度に1つずつ処理することです(IOストリームなしでメモリ内のすべてを実行するのに十分小さいデータセット)。これを行うためのより良い方法はありますか?
inには行の一部しか含まれていない可能性があるため( bufferSizeが小さい場合、各チャンクは10行になる可能性がありますが、は可変長であるため、 9.5行か何か)。これが、上記の質問に対する最善のアプローチが何であるか疑問に思っている理由です。chunk
stream.on('data', function(chunk) {});
id