【问题标题】:Why does using OpenURI to download a file result in a partial file?为什么使用 OpenURI 下载文件会导致文件不完整?
【发布时间】:2020-09-17 06:02:57
【问题描述】:

我正在尝试使用 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 的附件。

接下来我可以尝试什么?

【问题讨论】:

    标签: ruby-on-rails ruby actionmailer open-uri


    【解决方案1】:

    您似乎正在尝试在文件关闭之前读取文件,这可能会导致部分文件缓冲区未写入。

    我会这样做:

    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)
    

    【讨论】:

    • 谢谢!您碰巧知道如何将 ActionMailer 附件作为 StringIO 读取吗?所以我不必使用临时文件?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-16
    • 1970-01-01
    • 2019-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-15
    相关资源
    最近更新 更多