使用 boto 和 Python,我试图区分密钥是否返回文件文件夹(我知道 S3 对待两者的方式完全相同,因为我不直接处理文件系统)。
我现在有的是2把钥匙
<Key: my-folder,output/2019/01/28/>
<Key: my-folder,output/2019/01/28/part_1111>
第一个是"文件夹",第二个是"文件"。我想做的是确定密钥是否是"文件",但不确定如何确定这一点,显而易见的是密钥不以/
结尾,但我如何在 Python 中确定它。
如果我正在迭代list()
是否可以将键转换为字符串或访问键属性?
for obj in srcBucket.list():
# Get the Key object of the given key, in the bucket
k = Key(srcBucket, obj.key)
print(k)
<Key: my-folder,output/2019/01/28/>
<Key: my-folder,output/2019/01/28/part_1111>
S3。对象和 S3。对象摘要将具有以下属性:
"内容类型": "应用程序/x-目录"
如果键是目录。
for s3_obj_summary in bucket.objects.all():
if s3_obj_summary.get()['ContentType'] == 'application/x-directory':
print(str(s3_obj_summary))
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html#S3.ObjectSummary.get
您是正确的,文件夹不存在。例如,您可以创建一个名为 output/2020/01/01/foo.txt
的文件,即使这些子文件夹都不存在。
但是,某些系统喜欢通过使用假装文件夹的名称创建一个零长度对象来"创建"文件夹。在这种情况下,您可以通过检查对象的长度来识别"文件夹"。
下面是一些示例代码(使用 boto3 客户端方法):
import boto3
s3 = boto3.client('s3', region_name = 'ap-southeast-2')
response = s3.list_objects_v2(Bucket='my-bucket')
for object in response['Contents']:
if object['Size'] == 0:
# Print name of zero-size object
print(object['Key'])
正式地,没有理由存在这样的"文件夹文件"。没有它们,Amazon S3 将完美运行(而且由于您发现的原因,通常更好!
您需要检查每个对象的"键"和"大小":
for object in boto3.client('s3').list_objects_v2(Bucket='my-bucket')['Contents']:
if object['Size'] == 0 and object['Key'][-1] == '/':
print(f"Folder: {object['Key']}, (size: {object['Size']})")
elif object['Size'] == 0:
print(f"Zero-length file: {object['Key']}, (size: {object['Size']})")
else:
print(f"File: {object['Key']}, (size: {object['Size']})")
File: a_folder/a_file.txt, (size: 543)
Folder: a_folder/, (size: 0)
Zero-length file: a_folder/zero_length_file.txt, (size: 0)
文件夹对象也不一定具有['ContentType'] == 'application/x-directory'
:
for s3_obj_summary in boto3.resource('s3').Bucket('my-bucket').objects.all():
print(str(f"{s3_obj_summary.key}: {s3_obj_summary.get()['ContentType']}"))
a_folder/: application/octet-stream
找到文件时进行异常处理:
s3_client = boto3.client('s3')
paginator = s3_client.get_paginator('list_objects_v2')
pages = paginator.paginate(Bucket="logs", Prefix="logs/access/2022122700/")
for page in pages:
try:
for obj in page['Contents']:
print(obj['Key']) # prints fileName
except KeyError:
print("Doesn't exist")