You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用boto3查找S3对象前缀并按文件名更新对象

问题描述

我有一个已填充内容的S3存储桶,需要按指定文件名搜索并更新对应对象。存储桶里有带前缀的现有对象列表,我需要递归遍历所有对象(包含所有前缀目录),匹配目标文件名后通过S3文件上传更新它。

举个例子,存储桶根目录及子前缀下的对象如下:

cat2.jpg
cat3.jpg
PRE CAT_PICS/cat.jpg
PRE CAT_PICS/cat2.jpg
PRE CAT_PICS/MORE_CAT_PICS/cat3.jpg

现在要递归搜索并更新所有cat3.jpg对象,请问该怎么实现?另外,能不能提取找到的对象的前缀?

我自己写了一段代码,但不确定是否正确,而且因为缺少分页处理,没法覆盖超过1000个对象的情况:

当前代码:

import boto3

FILE_TO_UPDATE = cat3.jpg

s3_bucket = "example_bucket2182023"
s3_client = boto3.client("s3")

for my_bucket_object in my_bucket.objects.all():
    if my_bucket_object.endswith(FILE_TO_UPDATE):
        try:
            s3_client.put_object(
                Bucket=s3_bucket,
                key=my_bucket_object
            )
        except:
            print(f"Error uploading {my_bucket_object} to {s3_bucket}")

    print(my_bucket_object.key)
解决方案

1. 修复代码基础问题

你的现有代码存在几个明显错误:

  • FILE_TO_UPDATE未加引号,需定义为字符串:FILE_TO_UPDATE = "cat3.jpg"
  • 未初始化my_bucket对象,需通过boto3资源类创建:s3_resource = boto3.resource("s3"); my_bucket = s3_resource.Bucket(s3_bucket)
  • my_bucket_object是S3对象实例,需调用key属性才能做字符串匹配:my_bucket_object.key.endswith(FILE_TO_UPDATE)
  • put_object需指定上传内容(比如本地文件的Body参数),且Key参数要传入对象完整键值

2. 处理分页(支持1000+对象)

使用boto3资源类的Bucket.objects.all()会自动处理S3的1000条分页限制,无需手动处理ContinuationToken,直接遍历即可覆盖所有对象。

3. 提取对象前缀

通过字符串处理即可提取前缀:

  • 用os.path.dirname(object_key):如果对象是CAT_PICS/MORE_CAT_PICS/cat3.jpg,会返回CAT_PICS/MORE_CAT_PICS;如果是根目录的cat3.jpg,会返回空字符串

完整代码示例

import boto3
import os

# 配置参数
TARGET_FILENAME = "cat3.jpg"
S3_BUCKET_NAME = "example_bucket2182023"
LOCAL_FILE_PATH = "./cat3.jpg"  # 本地要上传的目标文件路径

# 初始化S3资源和客户端
s3_resource = boto3.resource("s3")
s3_client = boto3.client("s3")
my_bucket = s3_resource.Bucket(S3_BUCKET_NAME)

# 遍历所有对象(自动处理分页)
for obj in my_bucket.objects.all():
    object_key = obj.key
    # 精准匹配文件名(避免类似mycat3.jpg的误匹配)
    if os.path.basename(object_key) == TARGET_FILENAME:
        # 提取对象前缀
        object_prefix = os.path.dirname(object_key)
        print(f"找到匹配对象:{object_key},前缀:{object_prefix}")
        
        try:
            # 上传本地文件覆盖S3对象
            with open(LOCAL_FILE_PATH, "rb") as file:
                s3_client.put_object(
                    Bucket=S3_BUCKET_NAME,
                    Key=object_key,
                    Body=file
                )
            print(f"成功更新对象:{object_key}")
        except Exception as e:
            print(f"更新对象{object_key}失败:{str(e)}")

关键说明

  • 用os.path.basename()比endswith()更精准,避免文件名包含目标字符串的误匹配
  • 资源类的遍历方法自动处理分页,无需额外代码
  • 前缀提取逻辑兼容根目录和多级子目录的情况

内容的提问来源于stack exchange,提问作者asultan904

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 09:02:57