結論
s3_resource = Aws::S3::Resource.new(xxx)
s3_resource.bucket('BUCKET_NAME').object(KEY_NAME).get.body.read
背景
S3にアップロードしてある画像データを、RailsのViewで動的に表示したかった。
調べたこと
- S3に画像がどう格納されているか
- そもそもの画像データ
S3にどう画像が格納されているか
Amazon S3 は、一意のキー値を使用して、必要な数のオブジェクトを保存できるオブジェクトストアです。これらのオブジェクトは 1 つ以上のバケットに保存し、各オブジェクトのサイズは最大 5 TB です。
つまり、S3にアップロードしている画像やテキストデータ = オブジェクト
オブジェクトにアクセスできるのがキー。
オブジェクトを保管しているのがバケット。
## バケットのリスト取得
s3_resource.buckets
=> #<Aws::S3::Bucket::Collection:0x0000ffff584ea680
@batches=#<Enumerator: ...>,
@limit=nil,
@size=nil>
## バケット単体取得
s3_resource.buckets.first
=> #<Aws::S3::Bucket:0x0000ffff542af388
@arn=nil,
@client=#<Aws::S3::Client>,
@data=#<struct Aws::S3::Types::Bucket name="test_bucket", creation_date=2022-06-24 14:23:15.155 UTC>,
@name="test_bucket", # <-- bucket名 -->
@resolved_region="us-east-1",
@waiter_block_warned=false>
## バケット名を指定する
s3_resource.bucket("test_bucket")
#<Aws::S3::Bucket:0x0000ffff61881240
@arn=nil,
@client=#<Aws::S3::Client>,
@data=#<struct Aws::S3::Types::Bucket name="test_bucket", creation_date=2022-06-24 14:23:15.155 UTC>,
@name="test_bucket", # <-- bucket名 -->
@resolved_region="us-east-1",
@waiter_block_warned=false>
## バケット名を指定してオブジェクトのリスト取得する
s3_resource.bucket("test_bucket").objects
=> #<Aws::S3::ObjectSummary::Collection:0x0000ffff5c03cda0
@batches=#<Enumerator: ...>,
@limit=nil,
@size=nil>
## バケット名とオブジェクトのキーを指定してオブジェクトを取得する
s3_resource.bucket("test_bucket").object("1")
=> #<Aws::S3::Object:0x0000ffff5c145738
@bucket_name="test_bucket",
@client=#<Aws::S3::Client>,
@data=nil,
@key="1",
@waiter_block_warned=false>
ここまでで、オブジェクトにたどり着くことができましたが、画像ってどう取ればいいんだ?
という謎になり、画像について調べます。
そもそもの画像データ
バイナリデータ(binary data)とは、コンピュータが理解しやすいデータ(2進数で表現されたデータ)
バイナリデータは、画像ファイルや音声ファイル、動画ファイル、圧縮ファイルなど、コンピュータが扱えるファイルは、すべてバイナリデータです。
つまり、S3のオブジェクトからバイナリデータを取得すれば良いということがわかりました。
ここで、Aws::S3::Objectのドキュメントから、オブジェクトの読み込みのメソッドのget
を発見します。
s3_resource.bucket("test_bucket").object("1").get
=> #<struct Aws::S3::Types::GetObjectOutput
body=#<StringIO:0x0000ffff5c011ab0>,
delete_marker=nil,
accept_ranges="bytes",
expiration=nil,
restore=nil,
last_modified=2022-06-24 14:23:15 +0000,
content_length=24972,
etag="\"e4b088734dace101b4302a729f22cd70\"",
checksum_crc32=nil,
checksum_crc32c=nil,
checksum_sha1=nil,
checksum_sha256=nil,
missing_meta=nil,
version_id=nil,
cache_control=nil,
content_disposition=nil,
content_encoding=nil,
content_language=nil,
content_range=nil,
content_type="binary/octet-stream",
expires=nil,
expires_string=nil,
website_redirect_location=nil,
server_side_encryption=nil,
metadata={},
sse_customer_algorithm=nil,
sse_customer_key_md5=nil,
ssekms_key_id=nil,
bucket_key_enabled=nil,
storage_class=nil,
request_charged=nil,
replication_status=nil,
parts_count=nil,
tag_count=nil,
object_lock_mode=nil,
object_lock_retain_until_date=nil,
object_lock_legal_hold_status=nil>
戻り値であるAws::S3::Types::GetObjectOutput
の body
がStringIOの型だったので怪しいと思い、調べるとビンゴ。Object dataを返してくれるそうです。
https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Types/GetObjectOutput.html
s3_resource.bucket("test_bucket").object("1").get.body
=> #<StringIO:0x0000ffff60e958d0>
# StringIOを読み込む
s3_resource.bucket("test_bucket").object("1").get.body.read
=> "\xFF\xD8\xFF\xE0\u0000\u0010JFIF\u0000\u0001\xDB\u0000C\u0000\u0003\u0002\u0002\u0002\u0002\u0002\u0003\u0002\u0....
き、、きたーーー。2進数ではないけど見たことある画像データっぽいやつ!
これでS3から画像データを取得することができました。
わかったこと
- S3から画像を取得するには
Aws::S3::Types::GetObjectOutput
を使うこと - 画像データはバイナリデータ
- S3では画像などをオブジェクトという