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

上传至AWS S3的文件大小为0B的原因排查求助

问题原因与解决方案

核心问题分析

你遇到的0B文件上传问题,本质是两个关键错误导致:

  1. 文件指针耗尽:Flask的FileStorage是类文件对象,当你在save_picture中调用Image.open(form_picture)时,已经将文件指针读取到了末尾。后续调用s3.upload_fileobj(file)时,从当前指针位置开始读取,自然获取不到任何内容,因此上传的文件大小为0B。
  2. 未上传处理后的图片:当前代码上传的是前端传来的原始文件,而非save_picture中调整尺寸后的图片,完全不符合你的需求。

解决方案

修改代码逻辑,将处理后的图片保存到内存对象中,再上传至S3:

1. 导入必要模块

from io import BytesIO

2. 修改save_picture函数

让函数返回处理后的图片内存流和生成的文件名:

def save_picture(object_id, form_picture, path):
    if form_picture is None:
        return None, None
    random_hex = token_hex(8)
    filename = form_picture.filename
    if '.' not in filename:
        return None, None
    extension = filename.rsplit('.', 1)[1].lower()
    if not allowed_file(extension, form_picture):
        return None, None
    picture_fn = f'{object_id}_{random_hex}.{extension}'
    
    # 调整图片尺寸
    output_size = (1280, 720)
    i = Image.open(form_picture)
    i.thumbnail(output_size)
    
    # 将处理后的图片写入内存BytesIO对象
    img_bytes = BytesIO()
    # 根据图片扩展名选择对应保存格式(JPG需用'JPEG'格式)
    save_format = 'JPEG' if extension in ['jpg', 'jpeg'] else extension.upper()
    i.save(img_bytes, format=save_format)
    # 重置内存流指针到起始位置,方便后续读取上传
    img_bytes.seek(0)
    
    return picture_fn, img_bytes

3. 修改上传逻辑

使用处理后的内存流上传至S3:

image_name, processed_image = save_picture(object_id=new_object.id, form_picture=file, path=f'{object_type}_images')

if not image_name or not processed_image:
    return make_response({'msg': 'Invalid image file.'}, 400)

s3 = boto3.client(
    's3',
    aws_access_key_id=current_app.config['AWS_ACCESS_KEY'],
    aws_secret_access_key=current_app.config['AWS_SECRET_ACCESS_KEY']
)

try:
    s3.upload_fileobj(
        processed_image,
        current_app.config['AWS_BUCKET_NAME'],
        image_name,
        ExtraArgs={
            'ContentType': file.content_type
        }
    )
except Exception as e:
    print(e)
    return make_response({'msg': 'Something went wrong.'}, 500)

补充说明

如果你的需求是上传原始文件而非处理后的图片,仅需在上传前重置文件指针即可:

# 在调用save_picture后、上传前添加
file.seek(0)

s3.upload_fileobj(...)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 15:50:29