RubyのMechanizeを使って、1GB程度のファイルをダウンロードしようとすると以下のエラーメッセージが出ます。

C:/Ruby/lib/ruby/gems/1.8/gems/mechanize-1.0.0/lib/mechanize/chain/response_reader.rb:16:in `write': failed to allocate memory (NoMemoryError)
from C:/Ruby/lib/ruby/gems/1.8/gems/mechanize-1.0.0/lib/mechanize/chain/response_reader.rb:16:in `handle'

response_reader.rbの16行目付近は以下となります。
12: body = StringIO.new()
13: total = 0
14: @response.read_body { |part|
15: total += part.length
16: body.write(part)
17: Mechanize.log.debug("Read #{total} bytes") if Mechanize.log
18: }

恐らくStringIOオブジェクトのバッファが足りないのが原因と思われます。
writeを実行するたびにflushしようとしたのですが、StringIOのflushメソッドはselfを返すだけで実際にはメモリの内容をディスクに書き出さないようです。
flushする方法を調べたのですが、見付かりませんでした。どなたかご教授頂けますでしょうか。

環境は以下です。
Ruby(MRI) 1.8.7
Mechanize 1.0.0
Vista 64bit

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2010/04/06 22:06:08
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:t-wata No.1

回答回数82ベストアンサー獲得回数13

ポイント100pt

> StringIOのflushメソッドはselfを返すだけで実際にはメモリの内容をディスクに書き出さないようです。

SingIOって、ファイルの入出力はしないですよ。文字列オブジェクトでファイル入出力のメソッドを仮想的に使えるようにしたものがStringIOですから。

ファイルに書き込みたいなら、StringIO.newの代わりにopen("output.file.name", "w")にすればよいのでは?

id:anton0825

回答ありがとうございました。t-wadaさんから回答頂けるとは、びっくりです。ブログいつも拝見しています。

やはりFileオブジェクトを作ってflushさせるしかないですよね。

Mechanizeのget_fileメソッドを修正すべきと思いますので修正してコードをAuthorに送ってみます。

2010/04/06 11:07:55

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません