Net::SFTPとは
Rubyでリモートホストにファイルをコピーする一つの手段として、Net::SFTP というgemがある。
最小限の使い方は以下の通り。gem install net-sftpしてから
require 'net/sftp'
Net::SFTP.start('host', 'username', :password => 'password') do |sftp|
  # upload a file or directory to the remote host
  sftp.upload!("/path/to/local", "/path/to/remote")
  # download a file or directory from the remote host
  sftp.download!("/path/to/remote", "/path/to/local")
end
また、Net::SSHと一緒に使う場合は以下のようにもかける。
require 'net/ssh'
require 'net/sftp'
Net::SSH.start('remote_host') do |ssh|
  ssh.sftp.download!("/path/to/remote", "/path/to/local")
end
pure ruby実装なので、速度が気になる。ファイル転送速度をrsyncやscpと比較してみた。
速度比較
対象とするファイルは2つ。136MBのテキストファイルと、約1GBのbzip2圧縮されたバイナリファイル。
2つのマシンでの転送速度を比較した。
使ったrubyコード
require 'net/ssh'
require 'net/sftp'
Net::SSH.start('remote_host') do |ssh|
  ssh.sftp.download!(ARGV[0], ARGV[1])
  # ssh.sftp.upload!(ARGV[0], ARGV[1])
end
使用したrubyおよびrsync
- ruby 2.5.0
- net-ssh 4.2.0
 - net-sftp 2.1.2
 
 - rsync 2.6.9
 
結果
結果は以下の通り。それぞれ転送にかかった時間を表している。
rsyncは圧縮あり(-z)の場合となしの場合も比較した。
uploadの場合
| 136MB text file | 1GB binary file | |
|---|---|---|
rsync -az | 
6.7 | 12.9 | 
rsync -a | 
3.4 | 16.9 | 
scp | 
3.3 | 14.3 | 
| Net::SFTP | 5.4 | 21.3 | 
downloadの場合
| 136MB text file | 1GB binary file | |
|---|---|---|
rsync -az | 
6.9 | 13.9 | 
rsync -a | 
4.9 | 16.7 | 
scp | 
3.4 | 9.7 | 
| Net::SFTP | 61.6 | > 300 | 
当然ながらrsyncの方がNet::SFTPより速いのだが、uploadの場合はSFTPがrsyncより極端に遅いというわけではない。
しかし、downloadの場合はSFTPが極端に遅い。
実装がどうなっているのかは確認していないが、Net::SFTPのdownloadを使う場合は気をつける必要がありそうだ。