【问题标题】:What is the difference between send_data and send_file in Ruby on Rails?Ruby on Rails 中的 send_data 和 send_file 有什么区别?
【发布时间】:2011-07-29 00:05:11
【问题描述】:

哪一个最适合流式传输和文件下载?

请举例说明。

【问题讨论】:

    标签: ruby-on-rails ruby sendfile


    【解决方案1】:
    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 )
    

    【讨论】:

    • 感谢@fl00r。有没有办法使用 send_data 函数将数据保存为文件然后发送?因为,我需要服务器中的文件副本。我怎样才能做到这一点?。
    • 你的代码有错误:应该是{ |f| f &lt;&lt; data }
    • 嗨,我想知道这个答案是否仍然相关?我现在正在使用 Rails 3.2.16 并使用 send_file 我必须使用文件本身,而不是路径才能使其正常工作。只是想更新以防其他人遇到此问题?
    【解决方案2】:

    send_file 可能比 send_data 快

    作为fl00r mentionedsend_file 获取路径,send_data 获取数据。

    因此send_filesend_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-SendfileAsset Pipeline Guide 上讨论。

    【讨论】:

      猜你喜欢
      • 2010-11-17
      • 2011-01-23
      • 1970-01-01
      • 2010-09-14
      • 2011-10-19
      • 2018-03-26
      • 1970-01-01
      • 2011-04-25
      相关资源
      最近更新 更多