2012-05-08 72 views
19

我使用open-uri從遠程網站獲取圖像,並將它們保存在我的Ruby on Rails應用程序的本地服務器上。大多數圖像都沒有顯示出問題,但有些圖像沒有顯示出來。爲什麼OpenURI會將大小小於10kb的文件視爲StringIO?

一個很長的調試會話我終於找到了(感謝this blogpost),對於這種情況的原因是在此之後,class Bufferopen-uri-libary對待與文件大小小於作爲IO對象,而不是臨時文件10KB。

我設法從彌Winkelspecht回答以下至this 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?

由於上述代碼實際上重置了整個應用程序的全局行爲,我只是想確保我不會破壞其他任何東西。

回答

12

當您進行網絡編程時,您會分配一個相當大的緩衝區,併發送和讀取適合緩衝區的數據單位。但是,在處理文件時(或者有時稱爲BLOB),您不能認爲數據將適合您的緩衝區。所以,您需要對這些大量數據流進行特殊處理。 (有時適合緩衝區的數據單元稱爲數據包,但數據包實際上是第4層的東西,就像第2層的幀一樣。由於這發生在第7層,所以它們最好稱爲消息)

對於大於10K的回覆,open-uri庫設置額外開銷以寫入流對象。當在StringMax大小下時,它只是在消息中包含字符串,因爲它知道它可以放入緩衝區。

+0

謝謝,很好的解釋 – klaffenboeck

+3

不完全正確。在這種情況下用作緩衝區的字符串沒有固定的大小; Ruby中的字符串被動態調整大小。事實上,您可以動態調整大多數語言的緩衝區大小(儘管並非總是自動)。我懷疑爲小文件使用StringIO的真正原因是性能/內存使用權衡。 – pelle

+2

真@pelle。注意到你說的不完全。在BLOB的情況下,任何關於擬合的假設都可能被更大的BLOB破壞。這包括什麼不適合回憶。在某些情況下,處理流需要流式傳輸,而Buffer類選擇10K作爲轉折點,放棄流式處理文件。 –

相關問題