83

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

请提供例子。

4

2 回答 2

114
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

发送数据并保存文件:

data = "Hello World!"
file = "my_file.txt"
File.open(file, "w"){ |f| f << data }
send_data( data )
于 2011-04-04T08:28:30.243 回答
21

send_file 可能比 send_data 快

正如fl00r 提到的,send_file采用路径和send_data数据。

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

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

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

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

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

这更有效,因为反向代理在服务静态文件方面高度专业化,并且可以比 Rails 快得多(如果要发送文件数据,它不会发送文件数据X-Sendfile)。

的典型用例send_file是当您想要控制静态文件的访问权限时:您不能将它们放在下面/public,否则它们会在 Rails 有机会做出决定之前得到服务。这在以下位置进行了讨论:在 Rails 应用程序中保护 public/ 的内容

为了使用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(或config/environment/production.rb在 Rails 5.x 中),不是 application.rb,因为在开发中您没有代理服务器并且您想要send_file实际发送数据。

X-Sendfile在资产管道指南中进行了讨论。

于 2014-11-12T10:13:00.580 回答