23

リモート Web サイトから open-uri を使用して画像をフェッチし、Ruby on Rails アプリケーション内のローカル サーバーに保存します。ほとんどの画像は問題なく表示されましたが、一部の画像は表示されませんでした。

非常に長いデバッグ セッションの後、(このブログ投稿のおかげで) その理由はclass Bufferopen-uri- libary ではサイズが 10kb 未満のファイルが一時ファイルではなく IO オブジェクトとして扱われるためであることがわかりました。

Micah Winkelspecht からこの StackOverflow questionへの回答に従って、この問題を回避することができました。ここでは、初期化子のファイル内に次のコードを配置しました。

require 'open-uri'
# Don't allow downloaded files to be created as StringIO. Force a tempfile to be created.
OpenURI::Buffer.send :remove_const, 'StringMax' if OpenURI::Buffer.const_defined?('StringMax')
OpenURI::Buffer.const_set 'StringMax', 0

これは今のところ期待どおりに機能しますが、そもそもなぜこのコードをライブラリに入れているのか疑問に思っています。サイズが 10kb 未満のファイルが StringIO として扱われる特定の理由を知っている人はいますか?

上記のコードは、アプリケーション全体でこの動作を実質的にグローバルにリセットするため、他に何も壊していないことを確認したいだけです。

4

1 に答える 1

15

ネットワーク プログラミングを行うときは、適度に大きなサイズのバッファを割り当て、バッファに収まるデータ単位を送受信します。ただし、ファイル (または場合によっては BLOB と呼ばれるもの) を扱う場合、データがバッファーに収まるとは限りません。したがって、これらの大量のデータ ストリームには特別な処理が必要です。

(バッファに収まるデータの単位はパケットと呼ばれることもあります。ただし、フレームがレイヤー 2 にあるように、パケットは実際にはレイヤー 4 のものです。これはレイヤー 7 で発生しているため、メッセージと呼ばれる方がよいでしょう。)

10K を超える応答の場合、open-uri ライブラリは、ストリーム オブジェクトに書き込むための余分なオーバーヘッドを設定しています。StringMax サイズ未満の場合は、文字列がバッファに収まることがわかっているため、文字列をメッセージに含めるだけです。

于 2012-05-08T11:07:24.980 に答える