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

发布于 2024-10-30 16:25:01 字数 37 浏览 0 评论 0原文

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

请举例说明。

Which one is best for streaming and file downloads?

Please provide examples.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我纯我任性 2024-11-06 16:25:01
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 )
send_data(_data_, options = {})
send_file(_path_, options = {}) 

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

data = "Hello World!"
send_data( data, :filename => "my_file.txt" )

Or

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

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:

data = "Hello World!"
file = "my_file.txt"
File.open(file, "w"){ |f| f << data }
send_data( data )
隐诗 2024-11-06 16:25:01

send_file 可能比 send_data 更快,

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

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

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

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

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

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

这更加高效,因为反向代理高度专业化地提供静态文件,并且比 Rails 更快(如果发送 X-Sendfile,则不会发送文件数据)。

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

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

X-Sendfile资产管道指南<中进行了讨论/a>.

send_file may be faster than send_data

As fl00r mentioned, send_file takes a path, and send_data the data.

Therefore send_file is a subset of send_data, as you need a file on the filesystem: you could of course just read the file and use send_data on it. But send_file can be faster, so it is a performance / generality trade-off.

send_file can be faster because it can send the X-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.

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

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 app

In order to use the X-Sendfile headers, you have to add:

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

to config/initializers/production.rb (or config/environment/production.rb in Rails 5.x), not application.rb, since in development you don't have a proxy server and you want send_file to actually send the data.

X-Sendfile is discussed on the Asset Pipeline Guide.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文