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

如何将文件夹内多张图片上传至S3 Bucket,解决FileNotFoundError报错

问题原因

你遇到的FileNotFoundError核心原因是:

  • os.listdir()返回的仅为目录下的纯文件名,不包含你传入的父级路径path。你直接将纯文件名传入s3_client.upload_file()方法时,程序会默认从当前运行脚本的工作目录查找文件,而不是从你指定的待上传文件夹查找,因此触发文件不存在错误。
    除此之外你的现有代码还存在两个不符合批量上传预期的问题:
  • 如果指定了object_name参数,所有文件会被上传到S3的同一个对象路径,后上传的文件会直接覆盖之前的文件。
  • 异常捕获逻辑放在for循环外部,只要有一个文件上传失败,就会直接终止所有后续文件的上传,且无法定位具体出错的文件。
修复后可直接使用的代码
import os
import boto3
import logging
from botocore.exceptions import ClientError

def upload_files(path, bucket, object_prefix=None):
    """
    批量上传文件到S3存储桶

    :param path: 待上传文件所在的本地文件夹路径
    :param bucket: 目标S3存储桶名称
    :param object_prefix: 可选,S3对象名前缀,若不指定则直接使用原文件名作为对象名
    :return: 上传成功的文件数量
    """
    # 初始化S3客户端
    s3_client = boto3.client('s3')
    success_count = 0

    # 遍历目标文件夹
    for filename in os.listdir(path):
        # 拼接得到本地文件的完整路径
        local_full_path = os.path.join(path, filename)
        # 跳过子文件夹,仅上传文件
        if not os.path.isfile(local_full_path):
            continue
        
        # 生成S3端的对象名
        if object_prefix:
            s3_object_name = f"{object_prefix}/{filename}"
        else:
            s3_object_name = filename

        try:
            s3_client.upload_file(local_full_path, bucket, s3_object_name)
            success_count += 1
            logging.info(f"文件 {filename} 上传成功")
        except ClientError as e:
            logging.error(f"文件 {filename} 上传失败,错误信息:{e}")
    
    return success_count
核心修改说明
  • 拼接本地文件完整路径:使用os.path.join(path, filename)生成文件的完整访问路径,解决文件找不到的报错。
  • 动态生成S3对象名:如果传入前缀参数,会将所有文件上传到指定前缀下,文件名保持不变;如果不传入前缀,直接用原文件名作为S3对象名,避免文件覆盖。
  • 调整异常捕获位置:将异常处理移至循环内部,单个文件上传失败不会中断后续文件的上传,同时增加日志输出方便定位问题文件。
  • 返回上传成功计数:可以通过返回值快速校验批量上传的结果。

内容的提问来源于stack exchange,提问作者caleb-freitas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 10:54:01