使用boto3删除S3桶指定文件外其余文件并保留文件夹结构咨询
方案可行性判断
你设想的在每个文件夹下放置dummy占位文件的方案完全可行,这也是S3这类无实际目录结构的对象存储保留虚拟文件夹展示的通用实践方案。
S3的“文件夹”本质是控制台为贴合用户使用习惯渲染的虚拟层级,仅当存在前缀匹配该路径的对象时才会在界面展示,只要每个路径下始终保留至少1个未被删除的对象,对应虚拟文件夹就不会消失。
实现注意事项
- 建议统一命名占位文件为
.keep这类点开头的隐藏文件,默认不会在大部分文件管理器的普通视图中显示,对用户的正常上传操作干扰极小 - 占位文件可以上传为0字节的空文件,几乎不会产生额外存储成本
- 操作前建议先对存储桶开启版本控制,避免误删重要文件
参考boto3实现代码
批量删除(排除保留文件和占位文件)逻辑
import boto3 import botocore s3 = boto3.resource('s3') # 替换为你的存储桶名称 BUCKET_NAME = "your-bucket-name" # 替换为你需要额外保留的特定文件的完整对象Key RESERVED_FILE = "path/to/your/target/file.txt" bucket = s3.Bucket(BUCKET_NAME) to_delete = [] for obj in bucket.objects.all(): # 跳过指定保留文件,以及所有路径下的.keep占位文件 if obj.key == RESERVED_FILE or obj.key.endswith(".keep"): continue to_delete.append({"Key": obj.key}) # 批量删除,单次请求最多支持删除1000个对象,对象数量超过1000时会自动分页处理 if to_delete: for i in range(0, len(to_delete), 1000): batch = to_delete[i:i+1000] bucket.delete_objects( Delete={ "Objects": batch, "Quiet": True } )
批量初始化所有路径占位文件逻辑
如果你需要给桶内现有所有文件夹批量生成.keep占位文件,可以使用以下代码:
existing_dirs = set() for obj in bucket.objects.all(): # 拆分对象Key的所有父级路径 path_parts = obj.key.split("/")[:-1] current_dir = "" for part in path_parts: current_dir += f"{part}/" existing_dirs.add(current_dir) # 给每个路径上传.keep文件,已存在的跳过 for dir_path in existing_dirs: keep_key = f"{dir_path}.keep" try: s3.Object(BUCKET_NAME, keep_key).load() except botocore.exceptions.ClientError as e: if e.response["Error"]["Code"] == "404": bucket.put_object(Key=keep_key, Body=b"")
可选替代方案
如果不想额外存储占位文件,也可以在完成文件删除操作后,遍历所有原有路径,上传以/结尾的0字节空对象,同样可以实现保留虚拟文件夹的效果,只是实现复杂度比占位文件方案稍高。
内容的提问来源于stack exchange,提问作者Andrei
相关产品推荐
相关产品推荐

