Ruby on Railsを使ったSFTPへの接続やファイルのリストアップ、アップロード、ダウンロードを行う方法について見ていきましょう。
これから、SFTPサーバーに接続してやり取りするための Ruby on Railsのコードの書き方について、詳しくご説明します。SFTPは、安全なファイルおよびデータ転送を目的とした、広く使われている標準的で安全なプロトコルです。サーバとの接続の設定には、いくつかのステップがいるだけですので、この記事を読み終わる頃には、それをサッと簡単に実行できるようになりますよ。
要件
まずは準備です。Ruby on RailsでSFTPサーバに接続して対話するには、`net-sftp` gem が必要です。インストールの準備ができたら、手動で実行します。
gem install net-sftp
または`Gemfile`ファイルを作成し、その中で依存関係を宣言します。
gem 'net-sftp'
そして実行します:
bundle install
SFTPへの接続
この記事では、SFTPサーバーへの接続に必要な情報がすべて URI形式で格納された、 SFTPTOGO_URLという環境変数を使用します: sftp://user:password@host. この変数は URI.parse を使って URI の部分を抽出し、リモートサーバーのホストキーは~/.ssh/known_hosts
を使ってデフォルトで検証されます。
接続が確立されると、SFTP のクライアントオブジェクトがインスタンス変数 @sftp_client
に代入されます。
require 'net/sftp'
require 'uri'
class SFTPClient
def initialize(host, user, password)
@host = host
@user = user
@password = password
end
def connect
sftp_client.connect!
rescue Net::SSH::RuntimeError
puts "Failed to connect to #{@host}"
end
def disconnect
sftp_client.close_channel
ssh_session.close
end
def sftp_client
@sftp_client ||= Net::SFTP::Session.new(ssh_session)
end
private
def ssh_session
@ssh_session ||= Net::SSH.start(@host, @user, @password)
end
end
sftptogo_url = ENV['SFTPTOGO_URL']
begin
uri = URI.parse(sftptogo_url)
rescue URI::InvalidURIError
puts 'Bad SFTPTOGO_URL'
end
sftp = SFTPClient.new(uri.host, uri.user, password: uri.password)
sftp.connect
# disconnect
sftp.disconnect
ファイルの表示
接続が確立されたので、それを使ってリモート SFTP サーバー上のファイルを一覧表示することができます。これは @sftp_client.dir.for_each
メソッドを操作することによって行われ、それが path 引数で見つかったファイルに対応するオブジェクトの配列を返します。この例では、ラッパー関数は単にリモートパスで見つかったファイルを出力しています。
def list_files(remote_path)
@sftp_client.dir.foreach(remote_path) do |entry|
puts entry.longname
end
end
ファイルのアップロード
次のステップは、ファイルのアップロードです。sftp_client オブジェクトの upload
関数を使って、ローカルファイルのパスとリモートパス (アップロード後にファイルが置かれる場所と同じ) を渡します。ちなみに関数呼び出しは、@sftp_client.upload!("./local.txt", "./remote.txt")
となります。
def upload_file(local_path, remote_path)
@sftp_client.upload!(local_path, remote_path)
puts "Uploaded #{local_path}"
end
ファイルのダウンロード
プロセスの最終段階として、ファイルのダウンロードが必要です。sftp_client オブジェクトの download
関数を使って、リモートファイルのパスと、ダウンロードしたファイルを格納するローカルパスを渡します。この関数は @sftp_client.download("./remote.txt", "./download.txt")
のように呼び出します。
def download_file(remote_path, local_path)
@sftp_client.download!(remote_path, local_path)
puts "Downloaded #{remote_path}"
end
全体像
これで完了です!もし、このプログラムを最初から最後まで実行したい場合は、以下のコードをコピーして、 main.rb
という名前で保存してください:
require 'net/sftp'
require 'uri'
class SFTPClient
def initialize(host, user, password)
@host = host
@user = user
@password = password
end
def connect
sftp_client.connect!
rescue Net::SSH::RuntimeError
puts "Failed to connect to #{@host}"
end
def disconnect
sftp_client.close_channel
ssh_session.close
end
def upload_file(local_path, remote_path)
@sftp_client.upload!(local_path, remote_path)
puts "Uploaded #{local_path}"
end
def download_file(remote_path, local_path)
@sftp_client.download!(remote_path, local_path)
puts "Downloaded #{remote_path}"
end
def list_files(remote_path)
@sftp_client.dir.foreach(remote_path) do |entry|
puts entry.longname
end
end
def sftp_client
@sftp_client ||= Net::SFTP::Session.new(ssh_session)
end
private
def ssh_session
@ssh_session ||= Net::SSH.start(@host, @user, @password)
end
end
sftptogo_url = ENV['SFTPTOGO_URL']
begin
uri = URI.parse(sftptogo_url)
rescue URI::InvalidURIError
puts 'Bad SFTPTOGO_URL'
end
sftp = SFTPClient.new(uri.host, uri.user, password: uri.password)
sftp.connect
# list files in directory
sftp.list_files('/path/to/remote')
# upload files
sftp.upload_file('/path/to/local', '/path/to/remote')
# download files
sftp.download_file('/path/to/remote', '/path/to/local')
# disconnect
sftp.disconnect
最後に、以下のコマンドで実行します。:
ruby main.rb
やりました!Ruby on Railsを使ったSFTPへの接続ができましたよ!
もっとサンプルを見たい方はこちら。 Github