Boto3を使用して、フォルダーを取得せずにS3バケット内のすべてのファイルを取得するにはどうすればよいですか?
次のファイル構造を検討してください。
file_1.txt
folder_1/
file_2.txt
file_3.txt
folder_2/
folder_3/
file_4.txt
この例では、Imは4つのファイルにのみ関心があります。
編集:
手動による解決策は次のとおりです。
def count_files_in_folder(prefix):
total = 0
keys = s3_client.list_objects(Bucket=bucket_name, Prefix=prefix)
for key in keys['Contents']:
if key['Key'][-1:] != '/':
total += 1
return total
この場合、合計は4になります。
私がやったら
count = len(s3_client.list_objects(Bucket=bucket_name, Prefix=prefix))
結果は7つのオブジェクト(4つのファイルと3つのフォルダー)になります。
file.txt
folder_1/
folder_1/file_2.txt
folder_1/file_3.txt
folder_1/folder_2/
folder_1/folder_2/folder_3/
folder_1/folder_2/folder_3/file_4.txt
ただ欲しい:
file.txt
folder_1/file_2.txt
folder_1/file_3.txt
folder_1/folder_2/folder_3/file_4.txt
他の回答で述べられているように、s3には実際にはディレクトリツリーがありません。ただし、s3「フォルダー」のサイズがゼロであるという事実を利用して、ページネーターを使用することで便利な回避策があります。このコードスニペットは、バケット内のすべてのファイルのサイズが0より大きい場合に目的の出力を出力します(もちろん、リージョンを調整する必要があります)。
bucket_name = "bucketname"
s3 = boto3.client('s3', region_name='eu-central-1')
paginator = s3.get_paginator('list_objects')
[print(page['Key']) for page in paginator.paginate(Bucket=bucket_name).search("Contents[?Size > `0`][]")]
フィルタリングは JMESPath を使用して行われます。
注:もちろん、これはサイズ0のファイルも除外しますが、通常は空のファイル用のストレージは必要ありません。