Какой из них лучше всего подходит для потоковой передачи и загрузки файлов?
Приведите примеры.
Какой из них лучше всего подходит для потоковой передачи и загрузки файлов?
Приведите примеры.
Ответы:
send_data(_data_, options = {})
send_file(_path_, options = {})
Основное отличие здесь в том, что вы передаете ДАННЫЕ (двоичный код или что-то еще) с помощью send_data или PATH с помощью 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 )
{ |f| f << data }
.
send_file
мне пришлось использовать сам файл, а не путь, чтобы заставить его работать. Просто хотели обновить, если другие столкнутся с этим?
send_file может быть быстрее send_data
Как уже упоминалось , fl00rsend_file
принимает путь и send_data
данные.
Следовательно send_file
, это подмножество send_data
, поскольку вам нужен файл в файловой системе: вы, конечно, можете просто прочитать файл и использовать send_data
его. Но send_file
может быть и быстрее, так что это компромисс между производительностью и общностью.
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 сможет принять решение. Это обсуждается в: Защита содержимого публичного / в приложении 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/production.rb
(или config/environment/production.rb
в Rails 5.x), нет application.rb
, поскольку в процессе разработки у вас нет прокси-сервера, и вы send_file
действительно хотите отправлять данные.
X-Sendfile
обсуждается в Руководстве по конвейеру активов .