【问题标题】:Why does OpenURI treat files under 10kb in size as StringIO?为什么 OpenURI 将 10kb 以下的文件视为 StringIO?
【发布时间】:2012-05-16 20:01:05
【问题描述】:

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

经过很长的调试会话后,我终于发现(感谢this blogpost)这是因为open-uri-libary 中的class Buffer 将小于10kb 的文件视为IO 对象临时文件。

我按照 Micah 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 ?

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

【问题讨论】:

    标签: ruby standard-library


    【解决方案1】:

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

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

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

    【讨论】:

    • 不太正确。在这种情况下用作缓冲区的字符串没有固定大小; Ruby 中的字符串是动态调整大小的。实际上,您可以在大多数语言中动态调整缓冲区的大小(尽管并不总是自动)。我怀疑对小文件使用 StringIO 的真正原因是性能/内存使用权衡。
    • 真@pelle。注意到你说的不完全。在 BLOB 的情况下,关于拟合的任何假设都可能被更大的 BLOB 打破。这包括不适合记忆的内容。在某些时候处理流需要流,而 Buffer 类选择 10K 作为临界点,放弃并通过流处理文件。
    猜你喜欢
    • 1970-01-01
    • 2014-10-24
    • 1970-01-01
    • 1970-01-01
    • 2019-11-15
    • 2011-10-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多