从S3的API上来看,S3的资源分为Bucket和Object 2种类型。Bucket是S3根对象(如果S3是根目录的话,那么Bucket就是根目录下的文件夹),所有位于Bucket下的资源都是Object,但是其实Object可以分成目录和文件2种(虽然从API上是区分不出的,他们都是Object),但是可以通过他们的名字来区分,目录一定是以/结尾,而文件末尾肯定没有/。这个也是S3的API用以区分folder和file的关键。
这篇文件可以帮助理解:http://theburningmonk.com/2011/01/working-with-s3-folders-using-the-net-aws-sdk/
If you’ve been using S3 client in the AWS SDK for .Net you might have noticed that there are no methods that let you interact with the folders in a bucket. As it turns out,S3 does not support folders in the conventional sense*, everything is still a key value pair, but tools such asCloud Berry or indeed the Amazon web console simply uses ‘/’ characters in the key to indicate a folder structure.
This might seem odd at first but when you think about it, there are no folder structure on your hard drive either, it’s a logical structure theOS provides for you to make it easier for us mere mortals to work with.
Back to the topic at hand, what this means is that:
- if you add an object with key myfolder/ to S3, it’ll be seen as a folder
- if you add an object with key myfolder/myfile.txt to S3, it’ll be seen as a file myfile.txt inside a myfolder folder, if the folder object doesn’t exist already it’ll be added automatically
- when you make a ListObjects call both myfolder/ and myfolder/myfile.txt will be included in the result
Creating folders
To create a folder, you just need to add an object which ends with ‘/’, like this:
- public void CreateFolder(stringbucket, stringfolder)
- {
- var key =string.Format(@"{0}/", folder);
- var request =new PutObjectRequest().WithBucketName(bucket).WithKey(key);
- request.InputStream =new MemoryStream();
- _client.PutObject(request);
- }
Here is a thread on the Amazon forum which covers this technique.
Listing contents of a folder
With the ListObjects method on the S3 client you can provide a prefix requirement, and to get the list of objects in a particular folder simply add the path of the folder (e.g. topfolder/middlefolder/) in the request:
var request = new ListObjectsRequest().WithBucketName(bucket).WithPrefix(folder);
If you are only interested in the objects (including folders) that are in the top level of your folder/bucket then you’d need to do some filtering on theS3objects returned in the response, something along the line of:
- // get the objects at the TOP LEVEL, i.e. not inside any folders
- var objects = response.S3Objects.Where(o => !o.Key.Contains(@"/"));
- // get the folders at the TOP LEVEL only
- var folders = response.S3Objects.Except(objects)
- .Where(o => o.Key.Last() =='/' &&
- o.Key.IndexOf(@"/") == o.Key.LastIndexOf(@"/"));