rails – x-sendfile +临时文件

前段时间我写了一个关于在rails应用程序中使用临时文件的问题 。 在特定情况下,我决定使用tempfile

如果我还想使用x-sendfile指令( 作为Rails 2中的参数,或作为Rails 3中的配置选项 ),这会导致问题,因此文件发送由我的Web服务器直接处理,而不是我的rails应用程序。

所以我想做这样的事情:

 require 'tempfile' def foo() # creates a temporary file in tmp/ Tempfile.open('prefix', "#{Rails.root}/tmp") do |f| f.print('a temp message') f.flush send_file(f.path, :x_sendfile => true) # send_file f.path in rails 3 end end 

此设置有一个问题:文件在发送之前被删除!

一方面,一旦Tempfile.open块结束, tempfile就会删除该文件。 另一方面, x-sendfile使send_file调用异步 – 它返回的速度非常快,因此服务器几乎没有时间发送文件。

我现在最好的解决方案是使用非临时文件(File而不是Tempfile),然后是定期擦除temp文件夹的cron任务。 这有点不优雅,因为:

  • 我必须使用自己的临时文件命名方案
  • 文件在tmp文件夹上停留的时间比需要的时间长。

有更好的设置吗? 或者,异步send_file上至少有一个“成功”回调,所以我可以在完成后删除f吗?

非常感谢。

鉴于Rails3在可用时使用x-sendfile,并且无法停用它,你就不能将send_file与诸如TempFile之类的库一起使用。 最好的选择是我在问题中提到的那个:使用常规文件,并有一个cron任务定期删除旧的临时文件。

编辑:删除未使用的文件现在更容易处理maid gem:

https://github.com/benjaminoakes/maid

不要把send_file放在块中。

 f = Tempfile.new('prefix', "#{Rails.root}/tmp") f.print('a temp message') f.close send_file(f.path, :x-sendfile => true) 

然后使用另一个脚本来清理tempfile

file-temp gem怎么样? https://github.com/djberg96/file-temp

 require 'file/temp' fh = File::Temp.new(false) fh.puts "world" fh.close # => Tempfile still on your filesystem 

与zzzhc的答案一样,您需要在外部管理清理

您可以取消定义Tempfile实例的终结器,以便在销毁实例时永远不会删除您的文件,然后让chron任务处理它。

 require 'tempfile' def foo() # creates a temporary file in tmp/ Tempfile.open('prefix', "#{Rails.root}/tmp") do |f| f.print('a temp message') f.flush ObjectSpace.undefine_finalizer(f) # 'disables' deletion when GC'ed send_file(f.path, :x_sendfile => true) # send_file f.path in rails 3 end end