23

我从远程网站获取带有 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 的东西)时,您不能假设数据将适合您的缓冲区。因此,您需要对这些大型数据流进行特殊处理。

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

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

于 2012-05-08T11:07:24.980 回答