Edited at

RubyからS3を利用する

More than 1 year has passed since last update.


やりたいこと


  • S3にHTMLの文字列をファイルとしてアップロードしたい

  • S3に存在するHTMLファイルをダウンロードしたい

  • ファイルにタグ付けしたい



やってみる

S3を扱う際、というかAWS-SDKにはResourceとClientが存在する

今回はResourceを利用する



環境

ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin17]

aws-sdk (3.0.1)



初期設定

アクセスキーやデフォルトリージョンの設定のためにAWS CLIをインストールして

aws configureを行っておく



Resource作成

require 'aws-sdk'

s3 = Aws::S3::Resource.new



bucket作成

# bucket_name = 'test_bucket20180808'

# _はバケット名に使用できない
bucket_name = 'test-bucket20180808'
bucket = s3.bucket(bucket_name)
# バケット名は全世界で一意でなければならないので存在した場合作成できない
bucket.exists? # => false
bucket.create
bucket.exists? # => true



オブジェクトのアップロード



テキストをオブジェクトとしてアップロードする場合

file_name = "#{Time.now.strftime("%Y%m%d")}.html"

s3_path = "site_a"
key = "#{s3_path}/#{file_name}"
obj = bucket.object(key)
# bodyには任意の文字列を渡せる
obj.put(body: 'hogehoge')
# 存在確認
obj.exists? # => true
bucket.objects(prefix: 'site_a/').each{|obj| p key}
# => "site_a/20180808.html"



ファイルをアップロードする場合

file_name = "hoge_file"

s3_path = "site_b"
key = "#{s3_path}/#{file_name}"
obj = bucket.object(key)
obj.upload_file('log/test.log') # => ホーム指定ができない?
# 存在確認
obj.exists? # => true
bucket.objects(prefix: "site").each {|obj| p obj.key}
"site_a/20180808.html"
"site_b/hoge_file"



オブジェクトのダウンロード



文字列として読み込む

key = "site_a/20180808.html"

obj = bucket.objects(key)
obj.get.body.read



 ファイルとして保存する場合

key = "site_a/20180808.html"

obj = bucket.objects(key)
file_name = "hogehoge"
obj.download_file(file_name)


基本的にはgetやputではなく

upload_file,download_fileを利用した方が良い

後者はサイズが大きい時に

自動的にマルチアップロード、ダウンロードを行ってくれるため



オブジェクトにタグ付け


tags = {env: "dev", name: "hoge"}.to_query

# to_queryはRails依存だったかも?
# URLエンコードする必要がある
key = "tagtest"
obj = bucket.object(key)
obj.put(body: 'hogehoge', tagging: tags)
# upload_fileの際も同じオプションでおk

タグ付けしたはいいものの、タグで指定してgetができませんでした

あったら教えてください



階層内で最新を取る

# s3://test-bucketxxxx/site_a/以下の最新のオブジェクトがほしい、そんな時

bucket.objects(prefix: "site_a").sort_by{|obj| obj.last_modified}.reverse[0]



あとがき

やろうとしてることがS3でやることではない気がします

最新や、更新対象にタグ付けして管理するつもりだったのですが・・・