从同一存储桶中另一个子文件夹中的 s3 子文件夹中复制文件

Posted

技术标签:

【中文标题】从同一存储桶中另一个子文件夹中的 s3 子文件夹中复制文件【英文标题】:Copy file from s3 subfolder in another subfolder in same bucket 【发布时间】:2022-01-18 22:08:57 【问题描述】:

我想将文件从子文件夹复制到同一个 s3 存储桶中的另一个子文件夹中。我在 SO 中阅读了很多问题,最后我得到了这段代码。它有一个问题,当我运行它时它可以工作,但它不只复制文件,它会将包含文件的文件夹复制到我想要的目标位置,但在文件夹(根)中。如何只复制该子文件夹内的文件?

XXXBUCKETNAME:
    -- XXXX-input/  # I want to copy from here
    -- XXXX-archive/ # to here


import boto3
from botocore.config import Config
s3 = boto3.resource('s3', config=Config(proxies='https': getProperty('Proxy', 'Proxy.Host')))
bucket_obj = s3.Bucket('XXX')
destbucket = 'XXX'

jsonfiles = []
for obj in bucket_obj.objects.filter(Delimiter='/', Prefix='XXXX-input/', ):
    if obj.key.endswith('json'):
        jsonfiles.append(obj.key)
for k in jsonfiles:
    if k.split("_")[-1:][0] == "xxx.txt":
        dest = s3.Bucket(destbucket)
        source=  'Bucket' : destbucket, 'Key': k
        dest.copy(source, "XXXX-archive/"+k)

它给:

XXXBUCKETNAME:
    -- XXXX-input/
    -- XXXX-archive/
        -- XXXX-input/file.txt

我想要:

XXXBUCKETNAME:
    -- XXXX-input/
    -- XXXX-archive/
        -- file.txt

【问题讨论】:

在您调用 dest.copy 之前打印 "XXXX-archive/"+k 的值可以明确问题所在。 我知道有桶和对象而不是文件夹。 我是说复制命令中目标的简单调试日志会告诉您其值为XXXX-archive/XXXX-input/file.txt 啊,好吧,我当然打印了,但我的脑海中缺少对象的概念。 【参考方案1】:

在 S3 中确实没有任何“文件夹”。有桶和对象,如documentation 中所述。 UI 可能看起来像是有文件夹,但对象的关键是整个路径。因此,如果要复制一项,则需要解析其键并以不同方式构建目标键,以使其具有相同的前缀(路径)但以不同的值结尾。

在 Amazon S3 中,存储桶和对象是主要资源,并且 对象存储在桶中。 Amazon S3 具有扁平结构 类似于您在文件系统中看到的层次结构。然而,对于 为了组织简单,Amazon S3 控制台支持 文件夹概念作为对对象进行分组的一种方式。它通过使用 对象的共享名称前缀(即对象的名称以 使用公共字符串)。对象名称也称为键名。

在您的代码中,您将提取每个对象的密钥,这意味着密钥已经包含完整的“路径”,即使实际上并没有路径。因此,您将希望拆分 / 字符上的键,然后获取结果列表中的最后一个元素并将其附加为文件名:

dest.copy(source, "XXXX-archive/" + k.split("/")[-1])

【讨论】:

以上是关于从同一存储桶中另一个子文件夹中的 s3 子文件夹中复制文件的主要内容,如果未能解决你的问题,请参考以下文章

如何使用angular js将aws s3文件复制到同一个存储桶中的特定文件夹

复制同一 Amazon S3 存储桶中的文件

允许管理员访问 s3 存储桶中的子文件夹。保持所有其他文件夹公开

如何同时将视频上传到 s3 为其创建缩略图并使用 nodejs 将其保存到同一存储桶中的另一个文件夹中?

AWS S3策略限制用户仅列出存储桶中的某些文件夹

从 pyspark 访问 S3 存储桶中的文件