使用Python上传仅含图片的PDF到S3桶后文件为空,该如何解决?
问题根因
上传文件为空和PDF是否包含图片无关,是代码传参错误导致:
- boto3的
Object.put()方法的Body参数要求传入文件二进制内容、文件类对象等可读取的二进制流,你当前传入的是本地文件的路径字符串,S3只会把字符串本身的字节写入文件,导致文件内容异常。 - 额外问题:你代码里重复定义了
AWS_STORAGE_BUCKET_NAME变量,会覆盖掉前面带路径的定义,虽然你后来在filepath里补了前缀,但这种写法容易出问题,建议统一变量定义。 - 额外问题:每次循环都重复创建S3连接,会增加不必要的性能开销,建议把连接初始化放在循环外面。
修复后的代码
import os import boto3 import sys SERVICE_NAME = 's3' AWS_ACCESS_KEY_ID = 'XXXX' AWS_SECRET_ACCESS_KEY = 'XXXXX+A' AWS_S3_ENDPOINT_URL = 'https://s3.amazonaws.com' AWS_STORAGE_BUCKET_NAME = 'resolution-medical' S3_PREFIX = 'resolution_scanner/' source_folder = '/home/irfan/Downloads/test' # 把S3连接初始化移到循环外,避免重复创建 conn = boto3.resource( service_name=SERVICE_NAME, aws_access_key_id=AWS_ACCESS_KEY_ID, aws_secret_access_key=AWS_SECRET_ACCESS_KEY, endpoint_url=AWS_S3_ENDPOINT_URL ) arr = os.listdir(source_folder) for each in arr: file_full_path = os.path.join(source_folder, each) # 跳过文件夹,不需要捕获异常判断 if os.path.isdir(file_full_path): continue s3_file_path = os.path.join(S3_PREFIX, each) # 正确打开本地文件读取内容作为Body with open(file_full_path, 'rb') as f: conn.Object(AWS_STORAGE_BUCKET_NAME, s3_file_path).put( Body=f, ACL='public-read', ContentType='application/pdf' ) sys.exit()
其他优化说明
- 用
os.path.join拼接路径,避免不同操作系统路径分隔符差异导致的报错 - 直接用
os.path.isdir判断是否是文件夹,替代原来的捕获异常逻辑,代码更清晰 - 把S3前缀单独抽成变量,避免变量重复定义出错
内容的提问来源于stack exchange,提问作者Irfan Harun
相关产品推荐
相关产品推荐

