¿Cuál es la diferencia entre send_data y send_file en Ruby on Rails?
ruby-on-rails sendfile (2)
send_file puede ser más rápido que send_data
Como se menciona fl00r , send_file
toma una ruta y send_data
los datos a send_data
.
Por send_file
tanto, send_file
es un subconjunto de send_data
, ya que necesita un archivo en el sistema de archivos: por supuesto, puede leer el archivo y usar send_data
en él. Pero send_file
puede ser más rápido, por lo que es una compensación de rendimiento / generalidad.
send_file
puede ser más rápido porque puede enviar el encabezado X-Sendfile
en Apache ( X-Accel-Redirect
en Nginx) en lugar del contenido del archivo, ya que conoce la ruta.
Este encabezado es consumido por el proxy inverso (Apache o Nginx) que normalmente se ejecuta en frente de Rails en una configuración de producción.
Si X-Sendfile
está presente en la respuesta, el proxy inverso ignora la mayor parte de la respuesta actual y crea una nueva que devuelve el archivo en la ruta determinada.
Client <---> Internet <---> Reverse proxy <---> Rails
Esto es mucho más eficiente ya que el proxy inverso está altamente especializado para servir archivos estáticos, y puede hacerlo mucho más rápido que Rails (que no envía los datos del archivo si se envía X-Sendfile
).
El caso de uso típico de send_file
es cuando desea controlar el permiso de acceso de los archivos estáticos: no puede ponerlos en /public
o de lo contrario se publicarán antes de que Rails tenga la oportunidad de decidir. Esto se trata en: Protección del contenido del público / en una aplicación de Rails
Para usar los encabezados X-Sendfile
, debes agregar:
config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
config.action_dispatch.x_sendfile_header = ''X-Accel-Redirect'' # for nginx
a confing/initializers/production.rb
( no a application.rb
, ya que en desarrollo no tiene un servidor proxy y desea que send_file
envíe realmente los datos).
¿Cuál es el mejor para la transmisión y la descarga de archivos?
Por favor proporcione ejemplos.
send_data(_data_, options = {})
send_file(_path_, options = {})
La principal diferencia aquí es que pasa DATA (código binario o lo que sea) con send_data o file PATH con send_file .
Por lo tanto, puede generar algunos datos y enviarlos como texto en línea o como archivo adjunto sin generar archivos en su servidor a través de send_data . O puede enviar un archivo listo con send_file
data = "Hello World!"
send_data( data, :filename => "my_file.txt" )
O
data = "Hello World!"
file = "my_file.txt"
File.open(file, "w"){ |f| f << data }
send_file( file )
Para el rendimiento, es mejor generar el archivo una vez y luego enviarlo tantas veces como desee. Así que send_file
se ajustará mejor.
Para la transmisión, hasta donde yo entiendo, ambos métodos usan el mismo conjunto de opciones y configuraciones, por lo que puede usar X-Send o lo que sea.
UPD
send_data y guardar archivo:
data = "Hello World!"
file = "my_file.txt"
File.open(file, "w"){ |f| f << data }
send_data( data )