在Ruby on Rails中,在send_file方法之后从服务器中删除该文件

Che*_*ore 30 ruby ruby-on-rails file x-sendfile

我使用以下代码在Rails中发送文件.

if File.exist?(file_path)
  send_file(file_path, type: 'text/excel') 
  File.delete(file_path)
end

在这里,我试图发送文件,并在成功发送后从服务器中删除该文件.但我面临的问题是,删除操作是在发送执行时执行的,因为我在浏览器中看不到任何内容.

所以在Rails中有任何方法,一旦send_file操作完成,从服务器删除文件.

任何有关这方面的帮助将受到高度赞赏.

谢谢,
Chetan

Dyl*_*kow 39

因为您正在使用send_file,Rails会将请求传递给您的HTTP服务器(nginx,apache等 - 请参阅有关X-Sendfile头的send_file上的Rails文档).因此,当您尝试删除文件时,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)
Run Code Online (Sandbox Code Playgroud)

另一个选项是后台作业,定期检查要删除的临时文件.


小智 6

如果您正在即时生成要发送的文件,则解决方案是使用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
Run Code Online (Sandbox Code Playgroud)

此问题中指出的相反,这按预期工作(文件在服务器上停留的时间足够长以供服务,但最终被删除);这篇文章似乎表明这是由于 Rails 3.2.11 中的更新,我无法验证。

  • 我不会指望这个工作 100% 的时间。当 Tempfile 被垃圾收集时,它会删除文件,并且不能保证这会在 nginx/apache 打开文件之前发生。这取决于 Rails 中 send_file 的内部实现。send_data 是更好的选择。 (6认同)