5

How can I check if some folder exists in my s3 bucket using Ruby on Rails?

I’m using AWS:S3 official gem After initializing the global connection

AWS::S3::Base.establish_connection!(:access_key_id => 'my_key_id', :secret_access_key => ‘my_secret’) 

I have bucket named: myfirstbucket

With folder inside named: my_folder

With file inside my_folder named: my_pic.jpg

When I try to check if my_pic.jpg exist it work just fine

s3object.exists? “/my_folder/my_pic.jpg” , “myfirstbucket”
=>  True

How can I check only if the folder exists?

s3object = AWS::S3::S3Object
s3object.exists? “/my_folder/” , “myfirstbucket”
=>  False
Paul Roub
  • 36,322
  • 27
  • 84
  • 93
ofer goli
  • 91
  • 1
  • 1
  • 5
  • Possible duplicate of [Check if a key with a certain prefix exists in Amazon S3 bucket](http://stackoverflow.com/questions/9551347/check-if-a-key-with-a-certain-prefix-exists-in-amazon-s3-bucket) – Mark B Jul 09 '16 at 19:21

3 Answers3

6

Use Bucket#objects:

bucket.objects({prefix: 'my/folder/'}).limit(1).any?

Returns a Collection of ObjectSummary resources. No API requests are made until you call an enumerable method on the collection. Client#list_objects will be called multiple times until every ObjectSummary has been yielded.

http://docs.aws.amazon.com/sdkforruby/api/Aws/S3/Bucket.html#objects-instance_method

SoAwesomeMan
  • 3,226
  • 1
  • 22
  • 25
  • 3
    This seems like the only possible way to test for this condition because folder "foo/" never technically "exists" in S3. The "existence" of a folder is effectively defined by the existence of objects whose key prefix matches "foo/". – Michael - sqlbot Jul 09 '16 at 22:12
  • Yep. Or there's sparse or hard to find documentation about how to access via API the placeholder "dir" that a user can create and which persists via AWS S3 console. Here's an interesting article that is definitely talking about v1: http://deadprogrammersociety.blogspot.com/2008/01/making-s3-folders-in-ruby.html – SoAwesomeMan Jul 09 '16 at 23:36
  • Also we can call `S3::Client#list_objects_v2` directly as `resp = client.list_objects_v2(bucket: 'yourBucket', prefix: 'your/folder/', max_keys: 1)` and `resp.contents.any?`. – nekketsuuu Feb 07 '20 at 02:18
3

You have to check

  1. object key with trailing slash "/" is exists
  2. If not exists, Is there any item in the directory?

For example: You have file "my_file" under folder "my_folder". The AWS S3 record my_folder/my_file will exist offcourse, but my_folder/ may not exists.

So you have to check twice

if bucket.object("my_folder/").exists?
  true
else
  bucket.objects({prefix: "my_folder/"}).limit(1).any?
end

See the document: http://docs.aws.amazon.com/AmazonS3/latest/UG/FolderOperations.html

1

You could make a tree from you bucket.

http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/S3/Tree.html

tree = bucket.as_tree
tree.children.select(&:branch?).collect(&:prefix).include?(“/my_folder/”)
Albin
  • 2,912
  • 1
  • 21
  • 31