В чем разница между отправкой данных и отправкой файла в Ruby on Rails?
какой из них лучше всего подходит для потоковой передачи и загрузки файлов?
пожалуйста, приведите примеры.
2 ответов
send_data(_data_, options = {})
send_file(_path_, options = {})
основное отличие здесь в том, что вы передаете данные (двоичный код или что-то еще) с send_data или путь к файлу с send_file.
таким образом, вы можете генерировать некоторые данные и отправлять их как встроенный текст или как вложение без создания файла на вашем сервере через 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_file может быть быстрее, чем send_data
As fl00r упомянул, send_file
принимает путь, и send_data
данные.
send_file
- это подмножество send_data
, поскольку вам нужен файл в файловой системе: вы, конечно, можете просто прочитать файл и использовать send_data
на нем. Но!--2--> может быть быстрее, поэтому это компромисс производительности / общности.
send_file
может быть быстрее, потому что он может послать X-Sendfile
заголовок на Apache (X-Accel-Redirect
на Nginx) вместо содержимого файла, так как он знает путь.
этот заголовок потребляется обратным прокси (Apache или Nginx), который обычно работает перед Rails в производственной настройке.
если X-Sendfile
присутствует в ответе, обратный прокси игнорирует большую часть текущего ответа и создает новый, который возвращает файл по заданному пути.
Client <---> Internet <---> Reverse proxy <---> Rails
это много более эффективно, поскольку обратный прокси-сервер специализируется на обслуживании статических файлов и может делать это намного быстрее, чем Rails (который не отправляет данные файла, если X-Sendfile
будут посланы).
типичный случай использования send_file
- это когда вы хотите контролировать разрешение доступа к статическим файлам: вы не можете поместить их под /public
или они будут обслуживаться до того, как Rails имеет шанс решить. Это обсуждается по адресу:защита содержимого 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
до confing/initializers/production.rb
(не application.rb
, так как в разработке у вас нет прокси-сервера, и вы хотите send_file
фактически отправить данные).
X-Sendfile
обсуждается на Руководство По Трубопроводу Активов.