Lequel est le meilleur pour le streaming et les téléchargements de fichiers?
Veuillez fournir des exemples.
send_data(_data_, options = {})
send_file(_path_, options = {})
La principale différence ici est que vous passez DATA (code binaire ou autre) avec send_data ou fichier PATH avec send_file.
Vous pouvez donc générer des données et les envoyer sous forme de texte en ligne ou sous forme de pièce jointe sans générer de fichier sur votre serveur via send_data. Ou vous pouvez envoyer un fichier prêt avec send_file
data = "Hello World!"
send_data( data, :filename => "my_file.txt" )
Ou
data = "Hello World!"
file = "my_file.txt"
File.open(file, "w"){ |f| f << data }
send_file( file )
Pour les performances, il est préférable de générer le fichier une fois, puis de l'envoyer autant de fois que vous le souhaitez. Alors send_file
conviendra mieux.
Pour le streaming, si je comprends bien, ces deux méthodes utilisent le même tas d'options et de paramètres, vous pouvez donc utiliser X-Send ou autre chose.
UPD
send_data et enregistrez le fichier:
data = "Hello World!"
file = "my_file.txt"
File.open(file, "w"){ |f| f << data }
send_data( data )
send_file peut être plus rapide que send_data
Comme fl00r mentionné , send_file
Prend un chemin et send_data
Les données.
Par conséquent, send_file
Est un sous-ensemble de send_data
, Car vous avez besoin d'un fichier sur le système de fichiers: vous pouvez bien sûr simplement lire le fichier et utiliser send_data
Dessus. Mais send_file
Peut être plus rapide, c'est donc un compromis performance/généralité.
send_file
Peut être plus rapide car il peut envoyer l'en-tête X-Sendfile
sur Apache ( X-Accel-Redirect
sur Nginx ) au lieu du contenu du fichier, car il connaît le chemin d'accès.
Cet en-tête est consommé par le proxy inverse (Apache ou Nginx) qui s'exécute normalement devant Rails dans une configuration de production.
Si X-Sendfile
Est présent dans la réponse, le proxy inverse ignore la plupart de la réponse actuelle et en crée une nouvelle qui renvoie le fichier au chemin donné.
Client <---> Internet <---> Reverse proxy <---> Rails
Ceci est beaucoup plus efficace car le proxy inverse est hautement spécialisé dans le service de fichiers statiques et peut le faire beaucoup plus rapidement que Rails (qui n'envoie pas les données du fichier si X-Sendfile
Sera envoyé) .
Le cas d'utilisation typique de send_file
Est lorsque vous souhaitez contrôler l'autorisation d'accès des fichiers statiques: vous ne pouvez pas les placer sous /public
Ou bien ils seraient servis avant que Rails n'ait une chance de décider. Ceci est discuté à: Protéger le contenu du public/dans une Rails app
Pour utiliser les en-têtes X-Sendfile
, Vous devez ajouter:
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
(ou config/environment/production.rb
dans Rails 5.x), pas application.rb
, Car en cours de développement, vous n'avez pas de serveur proxy et vous voulez que send_file
Envoie réellement les données.
X-Sendfile
Est abordé dans le Asset Pipeline Guide .