【发布时间】:2011-07-29 00:05:11
【问题描述】:
哪一个最适合流式传输和文件下载?
请举例说明。
【问题讨论】:
标签: ruby-on-rails ruby sendfile
哪一个最适合流式传输和文件下载?
请举例说明。
【问题讨论】:
标签: ruby-on-rails ruby sendfile
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 )
【讨论】:
{ |f| f << data }。
send_file 我必须使用文件本身,而不是路径才能使其正常工作。只是想更新以防其他人遇到此问题?
send_file 可能比 send_data 快
作为fl00r mentioned,send_file 获取路径,send_data 获取数据。
因此send_file 是send_data 的子集,因为您需要文件系统上的文件:您当然可以只读取文件并在其上使用send_data。但是send_file 可以更快,所以这是性能/通用性的权衡。
send_file 可以更快,因为它可以在 Apache 上发送 X-Sendfile 标头(在 Nginx 上为 X-Accel-Redirect)而不是文件内容,因为它知道路径。
此标头由通常在生产设置中运行在 Rails 前面的反向代理(Apache 或 Nginx)使用。
如果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 实际上发送数据。
X-Sendfile 在Asset Pipeline Guide 上讨论。
【讨论】: