为什么OpenURI将10kb以下的文件视为StringIO?

我从远程网站用open-uri获取图像,并在Ruby on Rails应用程序中将它们保存在我的本地服务器上。 大多数图像显示没有问题,但有些图像没有出现。

经过一段很长的调试会话后,我终于发现了(感谢这篇博文 ),其原因是open-uri-libary中的class Buffer将大小小于10kb的文件视为IO对象而不是临时文件。

我设法通过Micah Winkelspecht对这个StackOverflow问题的回答解决了这个问题 ,我把以下代码放在我的初始化器中的一个文件中:

 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?

由于上面的代码实际上为我的整个应用程序全局重置了这种行为,我只想确保我没有破坏其他任何东西。

当进行网络编程时,您可以分配一个相当大的缓冲区,并发送和读取适合缓冲区的数据单元。 但是,在处理文件(或有时称为BLOB)时,您不能假设数据适合您的缓冲区。 因此,您需要对这些大型数据流进行特殊处理。

(有时适合缓冲区的数据单元称为数据包。但是,数据包实际上是第4层,就像帧在第2层。由于这发生在第7层,它们最好被称为消息。)

对于大于10K的回复,open-uri库正在设置写入流对象的额外开销。 当在StringMax大小下时,它只包含消息中的字符串,因为它知道它可以放在缓冲区中。