【发布时间】:2015-12-08 16:37:18
【问题描述】:
我的代码中有一个函数,它接受一个表示图像 url 的字符串,并从该字符串创建一个 File 对象,以附加到推文。这似乎在大约 90% 的时间都有效,但偶尔会失败。
require 'open-uri'
attachment_url = "https://s3.amazonaws.com/FirmPlay/photos/images/000/002/443/medium/applying_too_many_jobs_-_daniel.jpg?1448392757"
image = File.new(open(attachment_url))
如果我运行上面的代码,它会返回TypeError: no implicit conversion of StringIO into String。如果我将open(attachment_url) 更改为open(attachment_url).read,我会得到ArgumentError: string contains null byte。我也尝试像这样从文件中删除空字节,但这也没有任何区别。
image = File.new(open(attachment_url).read.gsub("\u0000", ''))
现在,如果我尝试使用不同图像的原始代码,如下图所示,它可以正常工作。它按预期返回一个File 对象:
attachment_url = "https://s3.amazonaws.com/FirmPlay/photos/images/000/002/157/medium/mike_4.jpg"
我认为这可能与原始 url 中的参数有关,所以我把它们去掉了,但没有任何区别。如果我在 Chrome 中打开图像,它们看起来还不错。
我不确定我在这里缺少什么。我该如何解决这个问题?
谢谢!
更新
这是我的应用程序中的工作代码:
filename = self.attachment_url.split(/[\/]/)[-1].split('?')[0]
stream = open(self.attachment_url)
image = File.open(filename, 'w+b') do |file|
stream.respond_to?(:read) ? IO.copy_stream(stream, file) : file.write(stream)
open(file)
end
Jordan 的答案有效,只是调用 File.new 返回一个空的 File 对象,而 File.open 返回一个包含来自 stream 的图像数据的 File 对象。
【问题讨论】:
-
从您的描述中不清楚:是不是这种情况,对于某些 jpg 文件 总是 失败,而对于某些其他文件 总是 成功,或者是不是对于给定的 URI,它有时会失败有时会成功?
-
对于某些文件总是失败,但对于其他文件永远不会。例如,第一个文件链接总是失败,而第二个文件链接总是成功。我怀疑文件本身可能有问题,所以我想知道如何检测和规避它。
-
如果它是二进制文件(如 JPEG),您不想去除空字节。这些是图像数据的一部分。