哪种方法最适合流媒体和文件下载?
请提供示例。
哪种方法最适合流媒体和文件下载?
请提供示例。
send_data(_data_, options = {})
send_file(_path_, options = {})
主要的区别在于你可以使用 send_data 传递数据(二进制代码或其他)或使用 send_file 传递文件路径。
因此,你可以生成一些数据并将其作为内联文本或附件发送,而无需通过 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 或其他方法。
更新
发送数据并保存文件:
data = "Hello World!"
file = "my_file.txt"
File.open(file, "w"){ |f| f << data }
send_data( data )
send_file 可能比 send_data 更快。
正如 fl00r提到的那样,send_file
使用文件路径,send_data
使用数据。
因此,send_file
是 send_data
的子集,因为它需要在文件系统上有一个文件:当然,你可以只读取文件并在其上使用 send_data
。但是,send_file
可能更快,因此这是性能/通用性权衡。
因为send_file
知道文件路径,所以它可以在Apache(X-Accel-Redirect
Nginx)上发送 X-Sendfile
头而不是文件内容。
反向代理(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
实际上发送数据。
X-Sendfile
在Asset Pipeline Guide中讨论。
{ |f| f << data }
。 - True Softsend_file
时我必须使用文件本身而不是路径才能使它工作。只是想更新一下,以防其他人遇到此类情况。 - FireDragon