如何将文件夹内多张图片上传至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
相关产品推荐
相关产品推荐

