确定文件夹或文件密钥是否为Boto



使用 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")

最新更新