【问题标题】:clean /tmp when send_file is over当 send_file 结束时清理 /tmp
【发布时间】:2020-06-15 17:35:05
【问题描述】:

我有一个 Redmine 插件。我在 /tmp 中创建一个临时文件,然后使用 File.open 发送它。我想在用户下载临时文件时删除它。我该怎么办?

我的代码(在控制器中):

File.open(filelocation, 'r') do |file|
  send_file file, :filename => filename, :type => "application/pdf", :disposition => "attachment"
end

如果我在 File.open 之后删除文件,它就不起作用。

编辑

在我的控制器中我这样做:

def something
  temp = Tempfile.new(['PDF_','.pdf'])
  # ... some code that modify my pdf ...

  begin
    File.open(temp.path, 'r') do |file|
      send_file file, :filename => temp.path, :type => "application/pdf", :disposition => "attachment"
    end

  ensure
    temp.close
    temp.unlink
  end

end

我的临时文件已删除,但不在我的代码末尾:File.open 返回损坏的 PDF。

【问题讨论】:

    标签: ruby redmine


    【解决方案1】:

    调用 send_file 可以卸载到 Web 服务器,因此它可以异步返回。在 tempfile 块中执行任何操作以及尝试关闭和取消链接文件都是危险的。使用 send_file 时,唯一的选择就是放弃清理 web 进程中的临时文件。

    【讨论】:

      【解决方案2】:

      考虑为您的工作使用Tempfile 类:

      Tempfile.create('foo', '/tmp') do |f|
         ... do something with f ...
      end
      

      它包含在标准库中,并且在关闭块时会自动进行清理。

      参考: http://www.ruby-doc.org/stdlib-2.1.1/libdoc/tempfile/rdoc/index.html

      【讨论】:

      • 谢谢,但它给了我NoMethodError (undefined method 'create' for Tempfile:Class) ...是因为我使用 ruby​​ 1.9.3 吗?
      • 是的。如果您坚持使用 1.9,则必须使用 Tempfile.new,这确实有点不同:ruby-doc.org/stdlib-1.9.3/libdoc/tempfile/rdoc/…
      【解决方案3】:

      我使用 send_data 而不是 send_file,然后我删除了文件。 send_data 将阻塞,直到数据发送完毕,允许 File.delete 请求成功。

       file = temp.path
       File.open(file, 'r') do |f|
         send_data f.read.force_encoding('BINARY'), :filename => filename, :type => "application/pdf", :disposition => "attachment"
       end
       File.delete(file)
      

      来源:In Ruby on Rails, After send_file method delete the file from server

      【讨论】:

        猜你喜欢
        • 2015-06-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-31
        • 2012-04-08
        • 1970-01-01
        • 1970-01-01
        • 2023-03-14
        相关资源
        最近更新 更多