Ruby on Rails 中的 send_data 和 send_file 有什么区别?
哪一种最适合流媒体和文件下载?
请举例说明。
Which one is best for streaming and file downloads?
Please provide examples.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这里的主要区别是您使用 send_data 传递 DATA(二进制代码或其他内容)或使用 send_file 传递文件 PATH。
因此,您可以生成一些数据并将其作为内联文本或附件发送,而无需通过 send_data 在服务器上生成文件。或者您可以使用 send_file 发送准备好的文件,
或者
为了性能,最好生成一次文件,然后根据需要多次发送。所以
send_file
更适合。对于流媒体,据我了解,这两种方法都使用相同的选项和设置,因此您可以使用 X-Send 或其他方法。
UPD
send_data 并保存文件:
Main difference here is that you pass DATA (binary code or whatever) with send_data or file PATH with send_file.
So you can generate some data and send it as an inline text or as an attachment without generating file on your server via send_data. Or you can send ready file with send_file
Or
For perfomance it is better to generate file once and then send it as many times as you want. So
send_file
will fit better.For streaming, as far as I understand, both of this methods use the same bunch of options and settings, so you can use X-Send or whatever.
UPD
send_data and save file:
send_file
可能比send_data
更快,正如 fl00r 提到的、
send_file
采用路径,send_data
采用数据。因此
send_file
是send_data
的子集,因为您需要文件系统上的文件:您当然可以只读取该文件并使用send_data
它。但send_file
可以更快,因此这是性能/通用性的权衡。send_file
可以更快,因为它可以发送X-Sendfile
< Apache 上的 /a> 标头(X-Accel-Redirect
上Nginx)而不是文件内容,因为它知道路径。此标头由反向代理(Apache 或 Nginx)使用,该代理通常在生产设置中在 Rails 前面运行。
如果响应中存在
X-Sendfile
,则反向代理会忽略当前响应的大部分内容,并构建一个新响应来返回给定路径处的文件。这更加高效,因为反向代理高度专业化地提供静态文件,并且比 Rails 更快(如果发送 X-Sendfile,则不会发送文件数据)。
send_file
的典型用例是当您想要控制静态文件的访问权限时:您不能将它们放在/public
下,否则它们将在 Rails 启动之前得到服务。有机会做出决定。对此进行了讨论:如何保护 public/ 的内容在 Rails 应用程序中为了使用
X-Sendfile
标头,您必须添加:到
config/initializers/development.rb
(或Rails 5.x 中的 config/environment/development.rb
),不是application.rb
,因为在开发中您没有代理服务器,并且您希望send_file
实际发送数据。X-Sendfile
在资产管道指南<中进行了讨论/a>.send_file
may be faster thansend_data
As fl00r mentioned,
send_file
takes a path, andsend_data
the data.Therefore
send_file
is a subset ofsend_data
, as you need a file on the filesystem: you could of course just read the file and usesend_data
on it. Butsend_file
can be faster, so it is a performance / generality trade-off.send_file
can be faster because it can send theX-Sendfile
header on Apache (X-Accel-Redirect
on Nginx) instead of the file content, since it knows the path.This header is consumed by the reverse proxy (Apache or Nginx) which normally runs in front of Rails in a production setup.
If
X-Sendfile
is present on the response, the reverse proxy ignores most of the current response, and builds a new one that returns the file at the given path.This is much more efficient since the reverse proxy is highly specialized at serving static files, and can do it much faster than Rails (which does not send the file data if
X-Sendfile
will be sent).The typical use case of
send_file
is when you want to control the access permission of static files: you cannot put them under/public
or else they would get served before Rails has a chance to decide. This is discussed at: How can I protect the content of public/ in a Rails appIn order to use the
X-Sendfile
headers, you have to add:to
config/initializers/production.rb
(orconfig/environment/production.rb
in Rails 5.x), notapplication.rb
, since in development you don't have a proxy server and you wantsend_file
to actually send the data.X-Sendfile
is discussed on the Asset Pipeline Guide.