7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

RubyでNet::SFTPを使うときはputsではなく、upload!を使おう

Last updated at Posted at 2019-09-02

環境

  • Ruby 2.6.3
  • Rails 5.2.3
  • net-sftp 2.1.2

前提

net-sftpとは、RubyでSSHプロトコルを使用し、暗号化を行なってファイルの送受信を行うことが出来るライブラリです。

ユースケースとしては外部システムと連携するときなどにアプリケーションのデータをファイル化して、外部サーバーに配置したりするとかだと思います。
https://github.com/net-ssh/net-sftp

Gemfileに以下を記述して、 bundle install すれば使えるようになります。

gem 'net-sftp'

具体的な net-sftp の使用方法は検索をすると結構出てくるので、割愛させていただきます。

起きた問題

putsを使って外部サーバーへファイルを保存する際大容量の書き込みがいつまで経っても終わらない問題に遭遇した。
以下が該当のコード

csv_str = 'hogehogeho,hogehoge,hogehoge' # csvフォーマットにした文字列が入っている
path = '/var/www' # 出力先のファイルパス
filename = 'hoge.csv' # 出力したいファイル名
Net::SFTP.start('host', 'user', :password => 'password') do |sftp|
  sftp.file.open("#{path}/#{filename}", 'w') do |f|
    f.puts csv_str
  end
end

ログを見た所、ロジックとしてはエラーとならずに f.puts csv_str で処理が止まって動かなくなっていた。

対応方法

ファイルを直接サーバーに書き込むのはやめ、一度 tmpディレクトリなどにファイルを配置してから、 upload!メソッドを使ってファイルのアップロードをすることで解決した。

具体的にどのくらいの容量から puts が動作しなくなるのかの計測が出来なかったので、基本的にはファイルのアップロードは puts ではなく、 upload!メソッドを使用するのがいいと思う

以下が具体的なコード

csv_str = 'hogehogeho,hogehoge,hogehoge' # csvフォーマットにした文字列が入っている
path = '/var/www' # 出力先のファイルパス
filename = 'hoge.csv' # 出力したいファイル名

tmp_dir = "#{Rails.root.to_s}/tmp"

# 一度tmpディレクトリへputsでファイルを生成する
File.open("#{tmp_dir}/#{filename}", "w") do |file|
  file.puts csv_str
end

# tmpディレクトリに作成したファイルをuploadする
Net::SFTP.start('host', 'user', :password => 'password') do |sftp|
  sftp.upload!("#{tmp_dir}/#{filename}", "#{path}/#{filename}")
end

net-sftpを使用する際は上記を気をつけて実装してみてください。

7
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?