我使用以下代码在Rails中发送文件。
if File.exist?(file_path) send_file(file_path, type: 'text/excel') File.delete(file_path) end
在此我尝试发送文件并在成功发送后从服务器中删除该文件。但我面临的问题是,删除操作是在发送执行时执行的,由于我在浏览器中没有看到任何内容。
一旦完成send_file操作,在Rails中有任何方法从服务器中删除文件。
对此的任何帮助都将受到高度赞赏。
谢谢,
阿赫亚
答案 0 :(得分:37)
因为您正在使用send_file
,Rails会将请求传递给您的HTTP服务器(nginx,apache等 - See the Rails documentation on send_file regarding X-Sendfile headers)。因此,当您尝试删除文件时,Rails不知道它仍在使用。
您可以尝试使用send_data
,这将阻止直到数据发送,从而允许您的File.delete
请求成功。请记住,send_data
需要数据流作为其参数,而不是路径,因此您需要首先打开文件:
File.open(file_path, 'r') do |f|
send_data f.read, type: "text/excel"
end
File.delete(file_path)
另一个选项是后台作业,定期检查要删除的临时文件。
答案 1 :(得分:4)
如果您正在动态生成您尝试发送的文件,解决方案是使用Tempfile
类:
begin
# The second argument is optional:
temp_file = Tempfile.new(filename, temp_directory)
# ... edit temp_file as needed.
# By default, temp files are 0600,
# so this line might be needed depending on your configuration:
temp_file.chmod(0644)
send_file temp_file
ensure
temp_file.close
end
与this question中的内容相反,这可以按预期工作(文件在服务器上停留的时间足够长,但最终会被删除); this post似乎表明这是由于Rails 3.2.11中的更新,我无法验证。
答案 2 :(得分:1)
这对我有用!
使用send_data
,您可以在发送之前删除文件。
file = File.open(Rails.root.join('public', 'uploads', filename), "rb")
contents = file.read
file.close
File.delete(filepath) if File.exist?(filepath)
send_data(contents, :filename => filename)