6

サーバー上に大きな CSV ファイルがあり、全体をメモリに読み込まずに、ダウンロードしてチャンクで処理したいと考えています。少し工夫した後、私はこれを思いつきました:

require open-uri

open("http://example.com/#{LARGE_CSV_FILE}") do |file|
  file.each_slice(50_000) do |fifty_thousand_lines|
    MyModel.import fifty_thousand_lines.join
  end
end

open-uri私の理解では、#openは HTTP GET をラップし、 -like のIOような列挙可能なオブジェクトを返します。#each_slice(n)一度に n 行の配列をブロックに渡します。次に、それらの行を結合して処理します。

これは問題なくインポートされ、OS X の iStat メニューを見ると、Ruby プロセスのメモリ使用量が手に負えないようには見えません。ただし、一度にすべてのファイルをダウンロードしたようです。メモリ使用量を爆発させずにこれを行うにはどうすればよいでしょうか?

Rubyはそれを一時ファイルにダウンロードしてから、ディスクから1行ずつ読み取りますか? open-uri代わりに、HTTP 接続を抑制し、ブロックがデータのバッチの処理を終了したときにのみ、より多くのデータをダウンロードすると考えていました。

これは、すべてのファイルをメモリにロードせずにファイルをダウンロードして処理する正しい方法ですか?

4

1 に答える 1