LoginSignup
85
60

More than 3 years have passed since last update.

これで大抵賄える!AWS SDK for Ruby V3でのS3操作まとめ!!

Posted at

S3の操作するコードを書くタスクは日常的にやるわけではなくて、なぜかちょうど忘れた頃の絶妙なタイミングでやってきます。そのたびにAPIリファレンスを見ながら頑張って組み立ててるような気がしたので、しゃらくせぇ!と思い、よく使うやつをまとめました。

Aws::S3::ClientAws::S3::Resourceの2系統を用意しました。お好みに応じて参照してください。
参考までに、この2つの違いがよく分からなくて途方に暮れている人はこちらをご覧ください。
AWS SDK for Ruby V3のAws::S3::ClientとAws::S3::Resourceの違いに正面から向き合う

クレデンシャル情報やリージョンは、環境変数やIAMロール等で設定されているものとします。
個別に設定する場合は、Aws::S3::Client.newAws::S3::Resource.newの引数に渡してあげてください。

Aws::S3::Client

# 共通
client = Aws::S3::Client.new

バケット一覧

# バケット情報一覧
client.list_buckets
=> #<struct Aws::S3::Types::ListBucketsOutput
 buckets=
  [#<struct Aws::S3::Types::Bucket name="bucket-01", creation_date=2017-09-16 14:07:03 UTC>,
   #<struct Aws::S3::Types::Bucket name="bucket-02", creation_date=2018-08-19 04:22:41 UTC>,],
 owner=#<struct Aws::S3::Types::Owner display_name="XXXXXX", id="xxxxxxxxxxxxxxx">>

# 各バケットを操作
client.list_buckets.buckets.each do |bucket|
  # なにかする
end

バケット作成

client.create_bucket(bucket: "bucket-03")
=> #<struct Aws::S3::Types::CreateBucketOutput location="http://bucket-03.s3.amazonaws.com/">

バケット削除

client.delete_bucket(bucket: "bucket-03")
=> #<struct Aws::EmptyStructure>

オブジェクト一覧

# オブジェクト情報一覧
# `list_objects`は使わない
client.list_objects_v2(bucket: "bucket-01")
=> #<struct Aws::S3::Types::ListObjectsV2Output
 is_truncated=true,
 contents=
  [#<struct Aws::S3::Types::Object key="example_01.txt", last_modified=2019-09-24 21:42:10 UTC, etag="\"xxxxxxxxxxxxxx\"", size=7, storage_class="STANDARD", owner=nil>,
   #<struct Aws::S3::Types::Object key="example_02.txt", last_modified=2019-09-24 21:42:10 UTC, etag="\"xxxxxxxxxxxxxx\"", size=7, storage_class="STANDARD", owner=nil>],
 name="bucket-01",
 prefix="",
 delimiter=nil,
 max_keys=1000,
 common_prefixes=[],
 encoding_type=nil,
 key_count=1000,
 continuation_token=nil,
 next_continuation_token="1I+AdtAyjlXhJ1jEKpdpR3fqz2bDnfJFEfZ+wgn9vmpXjHNGcLzL8bg==",
 start_after=nil>

# 各オブジェクトを操作(1000個以下の場合)
client.list_objects_v2(bucket: "bucket-01").contents.each do |object|
  # なにかする
end

# 各オブジェクトを操作(1000個より多いの場合)
options = {bucket: "bucket-01"}
loop do
  object_list = client.list_objects_v2(options)
  object_list.contents.each do |object|
    # なにかする
  end
  options[:continuation_token] = object_list.next_continuation_token
  break unless object_list.next_continuation_token
end

# キー名のプレフィクスによる絞り込み
client.list_objects_v2(bucket: "bucket-01", prefix: "hoge/").contents.each do |object|
  # なにかする
end

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

client.put_object(bucket: "bucket-01", key: "example_01.txt", body: "example")
=> #<struct Aws::S3::Types::PutObjectOutput
 expiration=nil,
 etag="\"xxxxxxxxxxxxxx\"",
 server_side_encryption=nil,
 version_id="JlDwEydDxlVNoyEaChzromzkjPo5FwVl",
 sse_customer_algorithm=nil,
 sse_customer_key_md5=nil,
 ssekms_key_id=nil,
 ssekms_encryption_context=nil,
 request_charged=nil>

オブジェクト読み込み

https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Client.html#get_object-instance_method
https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Types/GetObjectOutput.html

client.get_object(bucket: "bucket-01", :key => 'example_01.txt').body.read
=> "example"

オブジェクト削除

client.delete_object(bucket: "bucket-01", key: "example_01.txt")
=> #<struct Aws::S3::Types::DeleteObjectOutput delete_marker=true, version_id="skCZWAXC0.vhxjK6zKTF0dBkj4H0gEe8", request_charged=nil>

オブジェクトのバージョン操作

https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Client.html#list_object_versions-instance_method
https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Client.html#delete_object-instance_method

# バージョン情報
client.list_object_versions(bucket: "bucket-01", prefix: "example_01.txt")
=> #<struct Aws::S3::Types::ListObjectVersionsOutput
 is_truncated=false,
 key_marker="",
 version_id_marker="",
 next_key_marker=nil,
 next_version_id_marker=nil,
 versions=
  [#<struct Aws::S3::Types::ObjectVersion
  etag="\"xxxxxxxxxx\"",
  size=7,
  storage_class="STANDARD",
  key="example_01.txt",
  version_id="BcczH4ZRVunnKyBuzk3cBOQgrh1gtGpR",
  is_latest=true,
  last_modified=2019-09-24 21:47:54 UTC,
  owner=#<struct Aws::S3::Types::Owner display_name="xxxxxx", id="xxxxxxxxxxxxxxxxxx">>,
 #<struct Aws::S3::Types::ObjectVersion
  etag="\"xxxxxxxxxx\"",
  size=7,
  storage_class="STANDARD",
  key="example_01.txt",
  version_id="null",
  is_latest=false,
  last_modified=2019-09-24 21:42:10 UTC,
  owner=#<struct Aws::S3::Types::Owner display_name="xxxxxx", id="xxxxxxxxxxxxxxxxxx">>],
 name="bucket-01",
 prefix="example_01.txt",
 delimiter=nil,
 max_keys=1000,
 common_prefixes=[],
 encoding_type="url">

# 特定のバージョンを削除
client.delete_object(bucket: "bucket-01", prefix: "example_01.txt", version_id: "JlDwEydDxlVNoyEaChzromzkjPo5FwVl")
=> #<struct Aws::S3::Types::DeleteObjectOutput delete_marker=nil, version_id="JlDwEydDxlVNoyEaChzromzkjPo5FwVl", request_charged=nil>

マルチパートアップロード

https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Client.html#create_multipart_upload-instance_method
https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Client.html#upload_part-instance_method
https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Client.html#complete_multipart_upload-instance_method

multipart = client.create_multipart_upload(bucket: "bucket-01", key: "multipart")
=> #<struct Aws::S3::Types::CreateMultipartUploadOutput
 abort_date=nil,
 abort_rule_id=nil,
 bucket="bucket-01",
 key="multipart",
 upload_id="xxxxxxxxxxxxxxxxxxxx",
 server_side_encryption=nil,
 sse_customer_algorithm=nil,
 sse_customer_key_md5=nil,
 ssekms_key_id=nil,
 ssekms_encryption_context=nil,
 request_charged=nil>

part_01 = client.upload_part(bucket: "bucket-01", key: "multipart", body: File.open("/path/to/part_01"), part_number: 1, upload_id: multipart.upload_id)
=> #<struct Aws::S3::Types::UploadPartOutput
 server_side_encryption=nil,
 etag="\"xxxxxxxxxxxxxxxxxxxxx\"",
 sse_customer_algorithm=nil,
 sse_customer_key_md5=nil,
 ssekms_key_id=nil,
 request_charged=nil>

part_02 = client.upload_part(bucket: "bucket-01", key: "multipart", body: File.open("/path/to/part_02"), part_number: 2, upload_id: multipart.upload_id)
=> #<struct Aws::S3::Types::UploadPartOutput
 server_side_encryption=nil,
 etag="\"yyyyyyyyyyyyyyyyyyyyy\"",
 sse_customer_algorithm=nil,
 sse_customer_key_md5=nil,
 ssekms_key_id=nil,
 request_charged=nil>

client.complete_multipart_upload(
  bucket: "bucket-name-0001",
  key: "multipart",
  multipart_upload: {
    parts: [
      {etag: part_01.etag, part_number: 1},
      {etag: part_02.etag, part_number: 2}
    ]
  },
  upload_id: multipart.upload_id
)
=> #<struct Aws::S3::Types::CompleteMultipartUploadOutput
 location="https://bucket-01.s3.ap-northeast-1.amazonaws.com/multipart",
 bucket="bucket-01",
 key="multipart",
 expiration=nil,
 etag="\"zzzzzzzzzzzzzzzzzzzzz\"",
 server_side_encryption=nil,
 version_id="CSbIGreIivX2CTbIxj9Qz1JbePVQb2Qo",
 ssekms_key_id=nil,
 request_charged=nil>

署名付きURL作成

# clientではできない
signer = Aws::S3::Presigner.new
signer.presigned_url(:get_object, bucket: "bucket-01", key: "example_01.txt", expires_in: 3600)
=> "https://bucket-01.s3.ap-northeast-1.amazonaws.com/example_0001?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-...

Aws::S3::Resource

# 共通
resource = Aws::S3::Resource.new

バケット一覧

# バケット情報一覧
resource.buckets
=> #<Aws::S3::Bucket::Collection:0x00007fb1e3ccb6a8 @batches=#<Enumerator: ...>, @limit=nil, @size=nil>

# 各バケットを操作
resource.buckets.each do |bucket|
  # なにかする
end

バケット作成

resource.create_bucket(bucket: "bucket-03")
=> #<Aws::S3::Bucket:0x00007fb1e3d3f2d8 @client=#<Aws::S3::Client>, @data=nil, @name="bucket-03">

# こちらでもできるけど、Client系統で扱うbucket情報が返ってくる
resource.bucket("bucket-03").create

# 存在確認もできる
resource.bucket("bucket-03").exists?
=> true

バケット削除

resource.bucket("bucket-03").delete
=> #<struct Aws::EmptyStructure>

オブジェクト一覧

bucket = resource.bucket("bucket-01")

# オブジェクト情報
bucket.objects
=> #<Aws::S3::ObjectSummary::Collection:0x00007fb1e3e47a68 @batches=#<Enumerator: ...>, @limit=nil, @size=nil>

# 各オブジェクトを操作(1000個より多くてもOK!)
bucket.objects.each do |object|
  # なにかする
end

# キー名のプレフィクスによる絞り込み
bucket.objects(prefix: "hoge/").each do |object|
  # なにかする
end

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

https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Bucket.html#put_object-instance_method
https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Object.html#put-instance_method

bucket = resource.bucket("bucket-01")

# 文字列から
bucket.put_object(key: "example_01.txt", body: "example")
=> #<Aws::S3::Object:0x00007f859e9625c8 @bucket_name="bucket-01", @client=#<Aws::S3::Client>, @data=nil, @key="example_01.txt">

# ファイルから
bucket.put_object(key: "example_01.txt", body: File.open("example_01.txt"))
=> #<Aws::S3::Object:0x00007f859e9625c8 @bucket_name="bucket-01", @client=#<Aws::S3::Client>, @data=nil, @key="example_01.txt">

# こちらでもできるけど、Client系統で扱うbucket情報が返ってくる
bucket.object("example_01.txt").put(body: "example")
=> #<struct Aws::S3::Types::PutObjectOutput
 expiration=nil,
 etag="\"xxxxxxxxxxxxxxxxxxxxxxxxxxxx\"",
 server_side_encryption=nil,
 version_id=nil,
 sse_customer_algorithm=nil,
 sse_customer_key_md5=nil,
 ssekms_key_id=nil,
 ssekms_encryption_context=nil,
 request_charged=nil>

オブジェクト読み込み

bucket = resource.bucket("bucket-01")

bucket.object("example_01.txt").get.body.read
=> "example"

# 存在確認もできる
bucket.object("example_01.txt").exists?
=> true

オブジェクト削除

https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Bucket.html#delete-instance_method
https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/ObjectSummary/Collection.html#batch_delete!-instance_method

bucket = resource.bucket("bucket-01")

bucket.object("example_01.txt").delete
=> #<struct Aws::S3::Types::DeleteObjectOutput delete_marker=nil, version_id=nil, request_charged=nil>

# 一括削除
bucket.objects(prefix: "hoge/").batch_delete!
=> nil

オブジェクトのバージョン操作

https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Bucket.html#object_versions-instance_method
https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Object.html#delete-instance_method

bucket = resource.bucket("bucket-01")

bucket.object_versions(prefix: "example_01.txt").map(&:data)
=> [#<struct Aws::S3::Types::ObjectVersion
  etag="\"xxxxxxxxxx\"",
  size=7,
  storage_class="STANDARD",
  key="example_01.txt",
  version_id="BcczH4ZRVunnKyBuzk3cBOQgrh1gtGpR",
  is_latest=true,
  last_modified=2019-09-24 21:47:54 UTC,
  owner=#<struct Aws::S3::Types::Owner display_name="xxxxxx", id="xxxxxxxxxxxxxxxxxx">>,
 #<struct Aws::S3::Types::ObjectVersion
  etag="\"xxxxxxxxxx\"",
  size=7,
  storage_class="STANDARD",
  key="example_01.txt",
  version_id="null",
  is_latest=false,
  last_modified=2019-09-24 21:42:10 UTC,
  owner=#<struct Aws::S3::Types::Owner display_name="xxxxxx", id="xxxxxxxxxxxxxxxxxx">>]

# 特定のバージョンを削除
bucket.object("example_01.txt").delete(version_id: "BcczH4ZRVunnKyBuzk3cBOQgrh1gtGpR")
=> #<struct Aws::S3::Types::DeleteObjectOutput delete_marker=nil, version_id="BcczH4ZRVunnKyBuzk3cBOQgrh1gtGpR", request_charged=nil>

マルチパートアップロード

bucket = resource.bucket("bucket-01")

# デフォルトだと15MBより大きければマルチパートアップロードになる
# しきい値を変えたい場合は、`multipart_threshold`オプションを与える
bucket.object("very_large_file.txt").upload_file("/path/to/very_large_file")
=> true

署名付きURL作成

bucket = resource.bucket("bucket-01")

# `:get`/`put`/`head`/`delete`が指定できる
# `expires_in`はデフォルト900秒
bucket.object("example_01.txt").presigned_url(:get, expires_in: 3600)
=> "https://bucket-01.s3.ap-northeast-1.amazonaws.com/example_0001?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-...
85
60
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
85
60