Ruby on Rails中的send_data和send_file有什么区别?

时间:2011-04-04 08:08:57

标签: ruby-on-rails ruby sendfile

哪一个最适合流媒体和文件下载?

请提供示例。

2 个答案:

答案 0 :(得分:100)

send_data(_data_, options = {})
send_file(_path_, options = {}) 

这里的主要区别是您使用 send_data 传递DATA(二进制代码或其他)或使用 send_file 传递PATH。

因此,您可以生成一些数据并将其作为内嵌文本或附件发送,而无需通过 send_data 在服务器上生成文件。或者您可以使用 send_file

发送就绪文件
data = "Hello World!"
send_data( data, :filename => "my_file.txt" )

或者

data = "Hello World!"
file = "my_file.txt"
File.open(file, "w"){ |f| f << data }
send_file( file )

对于性能,最好生成一次文件,然后根据需要多次发送。所以send_file会更合适。

对于流式传输,据我所知,这两种方法都使用相同的选项和设置,因此您可以使用X-Send等。

<强> UPD

send_data并保存文件:

data = "Hello World!"
file = "my_file.txt"
File.open(file, "w"){ |f| f << data }
send_data( data )

答案 1 :(得分:18)

send_file可能比send_data

更快

作为fl00r mentionedsend_file采用路径,并send_data数据。

因此send_filesend_data的子集,因为您需要文件系统上的文件:您当然可以只读取文件并在其上使用send_data。但是send_file可以更快,所以这是一种表现/普遍性的权衡。

send_file可以更快,因为它可以在Apache上发送X-Sendfile标头(在Nginx上为X-Accel-Redirect)而不是文件内容,因为它知道路径。

此标头由反向代理(Apache或Nginx)使用,反向代理通常在生产设置中的Rails前运行。

如果响应中存在X-Sendfile,则反向代理会忽略当前响应的大部分,并构建一个在给定路径返回文件的新响应。

Client <---> Internet <---> Reverse proxy <---> Rails

由于反向代理高度专注于提供静态文件,因此效率更高,并且可以比Rails(如果将X-Sendfile将发送时不发送文件数据更快)。

send_file的典型用例是当您想要控制静态文件的访问权限时:您不能将它们置于/public之下,否则它们将在Rails有机会决定之前得到服务。这在以下讨论:Protecting the content of public/ in a Rails app

要使用X-Sendfile标题,您必须添加:

config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx

config/initializers/production.rb(或Rails 5.x中的config/environment/production.rb),不是 application.rb,因为在开发中你没有代理服务器而你希望send_file实际发送数据。

Asset Pipeline Guide上讨论了

X-Sendfile