我正在尝试使用OpenURI从S3下载文件,然后将其保存在本地,以便我可以将该文件作为附件发送给ActionMailer。
有些奇怪的事情正在发生。正在下载和附加的图像已损坏,图像的底部缺失。
以下是代码:
require 'open-uri'
open("#{Rails.root.to_s}/tmp/#{a.attachment_file_name}", "wb") do |file|
source_url = a.authenticated_url()
io = open(URI.parse(source_url).to_s)
file << io.read
attachments[a.attachment_file_name] = File.read("#{Rails.root.to_s}/tmp/#{a.attachment_file_name}")
end
a
是ActionMailer的附件。
有什么想法吗?我真的很感激你的想法,因为我一直在用这头撞墙。
答案 0 :(得分:9)
看起来你正试图在文件关闭之前读取文件,这可能会使部分文件缓冲区不成文。
我会这样做:
require 'open-uri'
source_url = a.authenticated_url()
attachment_file = "#{Rails.root.to_s}/tmp/#{a.attachment_file_name}"
open(attachment_file, "wb") do |file|
file.print open(source_url, &:read)
end
attachments[a.attachment_file_name] = File.read(attachment_file)
看起来source_url = a.authenticated_url()
将是一个字符串,因此将字符串解析为URI然后在其上执行to_s
将是多余的,除非URI正在进行一些规范化,我认为它不会
根据我的系统管理员经验:一项辅助任务是清理下载/假脱机文件。它们可以在连接后立即删除,或者你可以拥有一个每天运行的cron作业,删除所有假脱机文件超过一天。
另一个问题是,如果无法读取URL,则不会进行错误处理,从而导致附件失败。使用临时假脱机文件,您可以检查文件是否存在。更好的是,如果服务器返回400或500错误,您应该准备好处理异常。
要避免使用临时假脱机文件,请尝试以下未经测试的代码:
require 'open-uri'
source_url = a.authenticated_url()
attachments[a.attachment_file_name] = open(source_url, &:read)