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回まで
  • 13歳以上
  • 登録:2010/04/06 00:52:30
  • 終了:2010/04/06 22:06:08

ベストアンサー

id:t-wata No.1

t-wata回答回数82ベストアンサー獲得回数132010/04/06 03:21:31

ポイント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

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

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

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

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

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません