gov*_*sky 7 python google-cloud-storage google-cloud-platform
我从
client = storage.Client()
bucket = client.get_bucket(BUCKET_NAME)
<what's next? Need something like client.list_folders(path)>
Run Code Online (Sandbox Code Playgroud)
我知道如何:
列出所有 blob(包括任意深度的子子子文件夹中的 blob)bucket.list_blobs()
或如何递归列出给定文件夹中的所有 blobbucket.list_blobs(prefix=<path to subfolder>)
但是,如果我的文件系统结构具有100顶级文件夹,每个文件夹都有数千个文件,该怎么办?有什么有效的方法可以只获取那些100顶级文件夹名称而不列出所有内部 blob?
Rob*_*ino 11
这里的所有响应都有一个答案,但您需要在加载的迭代器中组合: the prefix、 thedelimiter和 the 。让我写下获取 100 个顶级文件夹的代码,然后我们将逐步完成它。prefixeslist_blobs(...)
import google.cloud.storage as gcs
client = gcs.Client()
blobs = client.list_blobs(
bucket_or_name=BUCKET_NAME,
prefix="",
delimiter="/",
max_results=1
)
next(blobs, ...) # Force list_blobs to make the api call (lazy loading)
# prefixes is now a set, convert to list
print(list(blobs.prefixes)[:100])
Run Code Online (Sandbox Code Playgroud)
在前八行中,我们构建 GCS 客户端并进行调用client.list_blobs(...)。在您的问题中,您提到了该bucket.list_blobs(..)方法 - 从版本 1.43 开始,该方法仍然有效,但文档中的 Buckets 页面表示该方法现已弃用。bucket_or_name唯一的区别是第 4 行的关键字 arg 。
我们希望文件夹位于顶层,因此我们实际上根本不需要指定prefix,但是,对于其他读者来说,如果您想在顶层目录中列出文件夹,stuff那么您应该指定一个尾部斜杠。这个 kwarg 将变成prefix="stuff/"。
有人已经提到了delimiterkwarg,但为了迭代,您应该指定它,以便 GCS 知道如何将 blob 名称解释为目录。够简单的。
这max_results=1是为了效率。请记住,我们在这里不需要 blob,我们只需要文件夹名称。因此,如果我们告诉 GCS 一旦发现单个斑点就停止寻找,它可能会更快。在实践中,我还没有发现这种情况,但如果你有大量的斑点,或者存储是冷线或其他什么,很可能会出现这种情况。YMMV。考虑它是可选的。
返回的对象blobs是一个延迟加载迭代器,这意味着它不会加载(甚至不会填充其成员),直到进行第一个 api 调用。为了获得第一次调用,我们请求next迭代器中的元素。就您而言,您知道您至少有一个文件,因此只需调用next(blobs)即可。它获取队列中的下一个(位于行的前面)的 blob,然后将其丢弃。
但是,如果您不能保证至少有一个 blob,则next(blobs)需要从迭代器返回某些内容的 将会引发StopIteration异常。为了解决这个问题,我们设置了省略号的默认值...。
blobs现在我们想要的成员prefixes, 已加载,我们打印出前 100 个。输出将类似于:
{'dir0/','dir1/','dir2/', ...}
Run Code Online (Sandbox Code Playgroud)
我认为如果不列出所有内部 blob,您就无法获得100 个顶级文件夹。谷歌云存储没有文件夹或子目录,该库只是创建了分层文件树的错觉。
我使用了这个简单的代码:
from google.cloud import storage
storage_client = storage.Client()
blobs = storage_client.list_blobs('my-project')
res = []
for blob in blobs:
if blob.name.split('/')[0] not in res:
res.append(blob.name.split('/')[0])
print(res)
Run Code Online (Sandbox Code Playgroud)