如何使用python将空的子文件夹上载到S3

如何使用python将空的子文件夹上载到S3,python,amazon-web-services,boto3,Python,Amazon Web Services,Boto3,下面的代码工作正常,除非有一个子文件夹,其中没有任何文件,那么子文件夹将不会出现在S3中。例如 如果/home/temp/subfolder没有文件,那么子文件夹将不会显示在S3中。如何更改代码,使空文件夹也上载到S3中? 我试图写一些东西(见下面的注释),但不知道如何将put_object()调用到空的子文件夹 #!/usr/bin/env python import os from boto3.session import Session path = "/home/temp" sessi

下面的代码工作正常,除非有一个子文件夹,其中没有任何文件,那么子文件夹将不会出现在S3中。例如 如果/home/temp/subfolder没有文件,那么子文件夹将不会显示在S3中。如何更改代码,使空文件夹也上载到S3中? 我试图写一些东西(见下面的注释),但不知道如何将put_object()调用到空的子文件夹

#!/usr/bin/env python
import os
from boto3.session import Session

path = "/home/temp"
session = Session(aws_access_key_id='XXX', aws_secret_access_key='XXX')
s3 = session.resource('s3')

for subdir, dirs, files in os.walk(path):
    # note: if not files ......
    for file in files:
        full_path = os.path.join(subdir, file)
        with open(full_path, 'rb') as data:

s3.Bucket('my_bucket').put_object(Key=full_path[len(path)+1:],    
Body=data)
此外,我尝试调用此函数来检查是否存在子文件夹或文件。它适用于文件,但不适用于子文件夹。如何检查子文件夹是否存在?(如果存在子文件夹,我将不上载)

顺便说一句,我参考了上面的代码

感谢他们共享代码。

S3中不存在目录(文件夹、子文件夹等)

将此文件复制到空的S3存储桶
/mydir/myfile.txt
时,仅将文件
myfile.txt
复制到S3。不会创建目录
mydir
,因为该字符串是文件名
mydir/myfile.txt
的一部分。实际文件名是完整路径,不存在或创建子目录

S3通过在bucket中列出文件时使用前缀来模拟目录。如果指定
mydir/
,则将返回以
mydir/
开头的所有S3对象,包括
mydir/anotherfolder/myotherfile.txt等对象。S3支持定界符,例如
/
,以便创建子目录的外观

注意:S3对象的文件名开头没有
/


谢谢你,约翰。所以没有办法上传一个空的子文件夹?我只想上传一个完整的目录,包括它的结构到S3,以便备份。奇怪的是,S3没有这样的备份机制。似乎我必须在本地压缩整个目录,然后将单个压缩文件上载到S3。S3上不存在目录,因此无法上载空目录。注意:一些软件产品在S3(CloudBerry)中创建模拟目录条目。这些实际上只是0长度的文件。如果您想将S3用作本地文件系统的备份克隆,则会遇到问题,因为S3不是文件系统,而是键值存储。创建zip文件然后上载zip文件是一种可行的方法。@user389955 S3不是分层的。文件不在“文件夹”中——这是S3扩展到基本上无限多个对象而性能没有变化的部分原因。如果你真的想在S3中“找到”一个文件夹,你可以上传一个名称以
/
结尾的空对象,但这只是一种错觉,它不会告诉你其中是否有任何内容(通过API删除它不会删除其中的文件)。如果你使用EFS,会发生这种情况吗?或者这是完全不同的吗?你的问题是,EFS中是否有空文件夹?答案是肯定的。EFS是一个文件系统,而S3是一个平面键/值存储设备。将S3看作只有一个目录(根目录)。所有文件,不管路径名如何,都存储在根目录中。这个问题多次与AWS S3 basic相关:S3是一个对象存储,所有对象名实际上是一个键名,它不支持文件夹。使用AWS控制台所看到的只是随意的。这就是为什么S3使用称为“PREFIX”的东西过滤掉共享相似前缀的对象名。这是让用户像文件夹一样系统地组织和过滤对象的唯一方法。
def check_exist(s3, bucket, key):
    try:
        s3.Object(bucket, key).load()
    except botocore.exceptions.ClientError as e:
        return False
    return True