我有一个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。
答案 0 :(得分:0)
考虑使用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
答案 1 :(得分:0)
我使用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
答案 2 :(得分:0)
呼叫 send_file 可以卸载到Web服务器,因此它可以异步返回。在tempfile块中执行任何操作都非常危险,同时也尝试关闭和取消链接该文件。使用send_file时,唯一的选择是放弃在Web进程中清理临时文件。