Vin*_*oft 3 python amazon-s3 amazon-web-services boto3
使用boto3,如何在不检索文件夹的情况下检索S3存储桶中的所有文件?
请考虑以下文件结构:
file_1.txt
folder_1/
file_2.txt
file_3.txt
folder_2/
folder_3/
file_4.txt
Run Code Online (Sandbox Code Playgroud)
在这个例子中我只对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
Run Code Online (Sandbox Code Playgroud)
在这种情况下,总数将是4.
如果我这样做的话
count = len(s3_client.list_objects(Bucket=bucket_name, Prefix=prefix))
Run Code Online (Sandbox Code Playgroud)
结果将是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
Run Code Online (Sandbox Code Playgroud)
我只是想:
file.txt
folder_1/file_2.txt
folder_1/file_3.txt
folder_1/folder_2/folder_3/file_4.txt
Run Code Online (Sandbox Code Playgroud)
moo*_*oot 15
S3是一个OBJECT STORE.它不提供目录服务.新来者总是混淆他们给出的"文件夹"选项,这实际上是对象的任意前缀.
object PREFIX是一种通过修复分组结构检索对象的方法.
您可以想象使用不允许您创建目录的文件系统,但允许您使用斜杠"/"或反斜杠"\"作为分隔符创建文件名,并且您可以通过以下方式表示文件的"级别"一个共同的前缀.
因此,在S3中,您使用以下"模拟目录"而不是目录.
folder1-folder2-folder3-myobject
folder1/folder2/folder3/myobject
folder1\folder2\folder3\myobject
Run Code Online (Sandbox Code Playgroud)
但是,为了帮助用户将批量文件传输到S3,aws cli,s3_transfer api等工具尝试简化步骤,并按照输入的本地文件夹结构创建对象名称.
因此,如果您确定所有S3对象都使用"/"作为分隔符,您实际上可以使用密钥名称进行简单下载(您必须首先通过提取密钥文件夹来创建文件夹,如分隔符结构)
这是使用资源迭代器的快速而脏的代码.使用s3.resource.object.filter将返回与list_objects()/ list_objects_v2()没有相同1000个键限制的迭代器.
import os
import boto3
s3 = boto3.resource('s3')
mybucket = s3.Bucket("mybucket")
# if blank prefix is given, return everything)
bucket_prefix="/some/prefix/here"
objs = mybucket.objects.filter(
Prefix = bucket_prefix)
for obj in objs:
path, filename = os.path.split(obj.key)
# boto3 s3 download_file will throw exception if folder not exists
try:
os.makedirs(path)
except FileExistsError:
pass
mybucket.download_file(obj.key, obj.key)
Run Code Online (Sandbox Code Playgroud)
S3中没有文件夹.你有四个名为的文件:
file_1.txt
folder_1/file_2.txt
folder_1/file_3.txt
folder_1/folder_2/folder_3/file_4.txt
Run Code Online (Sandbox Code Playgroud)
这些是S3中对象的实际名称.如果你想要的是最终:
file_1.txt
file_2.txt
file_3.txt
file_4.txt
Run Code Online (Sandbox Code Playgroud)
所有这些都位于本地文件系统的同一目录中,您需要操作对象的名称以仅删除文件名.像这样的东西会起作用:
import os.path
full_name = 'folder_1/folder_2/folder_3/file_4.txt'
file_name = os.path.basename(full_name)
Run Code Online (Sandbox Code Playgroud)
然后变量file_name将包含'file_4.txt'.
如果您确定没有文件以正斜杠结尾,则过滤出文件夹的一种方法是检查对象的结束字符:
for object_summary in objects.all():
if object_summary.key[-1] == "/":
continue
Run Code Online (Sandbox Code Playgroud)