Amazon S3 boto - 如何创建文件夹?

165

如何使用boto库在Amazon s3中创建存储桶下的文件夹?

我按照手册创建了密钥、权限和元数据等,但是在boto的文档中没有描述如何在存储桶中创建文件夹,或在存储桶的文件夹下创建文件夹。


似乎Amazon S3没有文件夹的概念,有人建议创建名称为“folder/test.txt”的键来解决这个问题。我尝试使用Firefox S3插件创建文件夹,并在Boto中列出所有键,它将我刚创建的文件夹输出为“<Key:vitoshares,everyone_$folder$>”,那么我该如何查看/添加/修改此文件夹中的内容? - vito huang
注意:AWS S3管理界面创建“文件夹”的选项不兼容S3FS,即使用接口创建“文件夹”,并尝试通过S3FS挂载点获取所述文件夹的列表。 - jldupont
注意2:通过S3FS创建“文件夹”与AWS S3管理界面兼容。 - jldupont
请参考@JaHax下面的答案,了解如何使用Boto完成此操作。非常简单! - e.thompsy
13个回答

175

S3中没有文件夹或目录的概念。您可以创建像"abc/xys/uvw/123.jpg"这样的文件名,许多S3访问工具(如S3Fox)会将其显示为目录结构,但实际上它只是存储于桶中的单个文件。


1
谢谢您的回答,那么我猜如果我想查看特定文件夹的内容,我需要遍历许多其他不必要的文件? - vito huang
8
有关文件夹的概念是非常明确的。答案是不正确的,请参见下面elranu的回答。 - Boppity Bop
27
@BoppityBop说:在S3中没有文件夹的概念。尽管管理控制台和许多工具将带斜杠的键表示为文件夹形式,但S3没有文件夹。请参见处理文件夹,并阅读部分:“因此,控制台使用对象键名称来呈现文件夹和层次结构。在Amazon S3中,您仅拥有存储桶和对象”。 - Antti Haapala -- Слава Україні
11
在技术上可能不算是文件夹,但肯定支持文件夹。在AWS控制台中查看存储桶时,可以点击“创建文件夹”来创建空的文件夹,并从中提取元数据。 - phazei
6
S3是一个巨大的、定制的DynamoDB键值存储库。一些工具(包括AWS Web控制台)提供了一些类似目录树的功能,但如果您的应用程序认为它等同于文件系统,则会使您反而与S3作斗争。例如,重命名看起来像一个目录的东西需要扫描整个keyspace并修改每个包含所讨论的“目录名称”的键。另一方面,作为一个键值存储器,不需要创建“父文件夹”或清理“空文件夹”,这是模拟文件系统所需要的。 - scooter-dangle
显示剩余3条评论

59

假设您想要在您的存储桶中创建文件夹abc/123/,使用Boto很容易实现

k = bucket.new_key('abc/123/')
k.set_contents_from_string('')

或者使用控制台


9
这是正确的答案。使用Boto是可行的,以下是操作步骤。实际上,您只需要使用new_key()函数。传递给该函数的字符串可以是abc/123/abc/123/newfile.txt,根据您的喜好而定。我建议在尝试获取所需内容后将其包装在if语句中,如下所示:key = bucket.get_key(upgrade_path) if key is None: key = bucket.new_key(upgrade_path) ,如果未找到,则创建它! - e.thompsy
2
使用最新的API,bucket.key('abc/123/')也可以实现相同的结果。 - rahulmishra
指定目录键也适用于在多部分上传中上传文件。mp = self._bucket.initiate_multipart_upload(bucket_key) - storm_m2138
7
我猜现在这可能已经过时了,或者问题应该包含一些有关“bucket”是什么的说明。在boto3中,似乎没有任何与S3相关的类中提供new_key方法。请注意,此方法已不再可用。 - Victor Schröder

41

使用这个:

import boto3
s3 = boto3.client('s3')
bucket_name = "YOUR-BUCKET-NAME"
directory_name = "DIRECTORY/THAT/YOU/WANT/TO/CREATE" #it's name of your folders
s3.put_object(Bucket=bucket_name, Key=(directory_name+'/'))

谢谢您的帮助,我遇到了以下错误。您能帮我吗?botocore.exceptions.NoCredentialsError: 无法找到凭据。 - Anvesh
1
你需要以某种方式指定你的AWS凭证。请查看:https://boto3.readthedocs.io/en/latest/guide/configuration.html#guide-configuration - Deepak G M

23

使用AWS SDK .Net非常完美,只需在文件夹名称字符串末尾添加"/"即可:

var folderKey =  folderName + "/"; //end the folder name with "/"
AmazonS3 client = Amazon.AWSClientFactory.CreateAmazonS3Client(AWSAccessKey, AWSSecretKey);
var request = new PutObjectRequest();
request.WithBucketName(AWSBucket);
request.WithKey(folderKey);
request.WithContentBody(string.Empty);
S3Response response = client.PutObject(request);

然后刷新您的AWS控制台,您将看到该文件夹


刚刚尝试了使用AWS :: S3 Ruby库。它创建了一个带有空文件名的“文件夹”...所以它并没有真正起作用。然而,Mohammad Asgari的解决方案很好! - Nico
@Nico,你的文件名后面加了“/”吗?就像代码注释里说的那样? - elranu
是的,我添加了斜杠。我使用AWS::S3::S3Object.store('test/', '', 'my_bucket')方法。 - Nico
使用空字符串和斜杠结尾的"putObject"对我有效。我正在使用tpyo/amazon-s3-php-class库的PHP版本。 - MikeMurko
当然AWS有文件夹。看看你的S3控制台。有一个创建文件夹按钮。这个答案是正确的答案..只需要努力一下.. - Boppity Bop
2
@BoppityBop 是的,它有一个创建文件夹按钮,但那可能只是创建了某种空文件。 - jamylak

12

我尝试了上述多种方法并在键名末尾添加正斜杠/来创建目录,但对我来说都没有起作用:

client.put_object(Bucket="foo-bucket", Key="test-folder/")
你需要提供 Body 参数才能创建目录:
client.put_object(Bucket='foo-bucket',Body='', Key='test-folder/')

来源:ryantuck在boto3问题中的评论


最佳答案终将浮出水面。谢谢! - curiouscheese

7

创建文件夹的方式已经不再适用。您应该尝试@TomNg建议的方法。 - radalin

5

2019年更新,如果您想创建包含路径bucket_name/folder1/folder2的文件夹,可以使用以下代码:

from boto3 import client, resource

class S3Helper:

  def __init__(self):
      self.client = client("s3")
      self.s3 = resource('s3')

  def create_folder(self, path):
      path_arr = path.rstrip("/").split("/")
      if len(path_arr) == 1:
          return self.client.create_bucket(Bucket=path_arr[0])
      parent = path_arr[0]
      bucket = self.s3.Bucket(parent)
      status = bucket.put_object(Key="/".join(path_arr[1:]) + "/")
      return status

s3 = S3Helper()
s3.create_folder("bucket_name/folder1/folder2)

4

创建文件夹非常容易。实际上,只需创建键。

你可以看到我下面的代码,我正在创建一个以utc_time为名称的文件夹。

请记住以'/'结尾的键,如下所示,这表示它是一个键:

Key='folder1/' + utc_time + '/'

client = boto3.client('s3')
utc_timestamp = time.time()


def lambda_handler(event, context):

    UTC_FORMAT = '%Y%m%d'
    utc_time = datetime.datetime.utcfromtimestamp(utc_timestamp)
    utc_time = utc_time.strftime(UTC_FORMAT)
    print 'start to create folder for => ' + utc_time

    putResponse = client.put_object(Bucket='mybucketName',
                                    Key='folder1/' + utc_time + '/')

    print putResponse

2

虽然你可以通过在文件夹名称后添加“/”来创建文件夹。但是,在底层,S3维护的是平面结构,而不是常规NFS。

var params = {
            Bucket : bucketName,
            Key : folderName + "/"
        };
s3.putObject(params, function (err, data) {});

0

以下代码使用Python的boto3库实现

s3 = boto3.client("s3")
s3.put_object(Bucket="dest_bucket", Key='folder_name/')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接