web-dev-qa-db-ja.com

Ruby on Railsのsend_dataとsend_fileの違いは何ですか?

ストリーミングとファイルのダウンロードに最適なのはどれですか?

例を提供してください。

75
Mr. Black
send_data(_data_, options = {})
send_file(_path_, options = {}) 

ここでの主な違いは、send_dataでDATA(バイナリコードなど)を渡すか、send_fileで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 )

パフォーマンスを向上させるには、ファイルを1回生成してから、必要な回数だけ送信することをお勧めします。そう send_fileの方が適しています。

ストリーミングに関しては、私が理解している限りでは、この両方の方法で同じオプションと設定が使用されるため、X-Sendなどを使用できます。

[〜#〜] upd [〜#〜]

send_dataおよび保存ファイル:

data = "Hello World!"
file = "my_file.txt"
File.open(file, "w"){ |f| f << data }
send_data( data )
101
fl00r

send_fileはsend_dataより高速かもしれません

fl00rが言及したようにsend_fileはパスを取り、send_dataはデータを取ります。

したがって、send_filesend_dataのサブセットです。ファイルシステムにファイルが必要なため、もちろんファイルを読み取ってsend_dataを使用できます。ただし、send_fileはより高速になる可能性があるため、パフォーマンスと汎用性のトレードオフです。

send_fileは、Apacheで X-Sendfile ヘッダーを送信できるため、高速になります( X-Accel-Redirect Nginxの場合)ファイルコンテンツの代わりに、パスを知っているため。

このヘッダーは、通常、プロダクションセットアップでRailsの前で実行されるリバースプロキシ(ApacheまたはNginx)によって消費されます。

X-Sendfileが応答に存在する場合、リバースプロキシは現在の応答のほとんどを無視し、指定されたパスのファイルを返す新しい応答を作成します。

Client <---> Internet <---> Reverse proxy <---> Rails

これは、リバースプロキシが静的ファイルの提供に高度に特化されており、Rails(X-Sendfileが送信される場合にファイルデータを送信しない)よりもはるかに高速に処理できるため、はるかに効率的です。

send_fileの典型的な使用例は、静的ファイルのアクセス許可を制御する場合です。静的ファイルを/publicの下に置くことはできません。そうしないと、Railsがチャンスを得る前に提供されます決定する。これについては、 Railsアプリ内のpublic /のコンテンツの保護について説明します

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)、notapplication.rb 、開発中にはプロキシサーバーがなく、send_fileが実際にデータを送信する必要があるためです。

X-SendfileAsset Pipeline Guide で説明されています。