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

如何修改基于streaming_form_data的FastAPI代码,将文件存至内存而非磁盘?

修改方案:将文件存储至内存而非磁盘

要避免磁盘I/O操作,只需替换原代码中的FileTarget为自定义的内存存储目标类,用内存缓冲区保存上传的文件数据。具体修改步骤如下:

1. 补充导入模块

新增io.BytesIO用于实现内存缓冲:

from io import BytesIO

2. 定义内存存储目标类

实现MemoryTarget类替代FileTarget,将上传数据写入内存缓冲区:

class MemoryTarget:
    def __init__(self, validator=None):
        self.buffer = BytesIO()
        self.validator = validator  # 保留原文件大小验证逻辑

    def data_received(self, chunk):
        # 先执行大小验证(如果配置了验证器)
        if self.validator:
            self.validator(chunk)
        # 将数据写入内存缓冲区
        self.buffer.write(chunk)

    @property
    def value(self):
        # 获取完整的文件字节数据
        self.buffer.seek(0)
        return self.buffer.read()

3. 调整上传接口逻辑

删除原代码中与磁盘存储相关的代码,替换为MemoryTarget:

@app.post('/upload')
async def upload(request: Request):
    body_validator = MaxBodySizeValidator(MAX_REQUEST_BODY_SIZE)
    filename = request.headers.get('Filename')
    
    if not filename:
        raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, 
            detail='Filename header is missing')
    try:
        # 替换FileTarget为自定义的MemoryTarget
        file_ = MemoryTarget(validator=MaxSizeValidator(MAX_FILE_SIZE))
        data = ValueTarget()
        parser = StreamingFormDataParser(headers=request.headers)
        parser.register('file', file_)
        parser.register('data', data)
        
        async for chunk in request.stream():
            body_validator(chunk)
            parser.data_received(chunk)
        
        # 解析完成后,直接从内存获取文件数据
        file_content = file_.value
        data_content = data.value.decode('utf-8')
        
        # 此处可添加对内存中文件数据的后续处理逻辑
        return {
            'filename': filename,
            'file_size': len(file_content),
            'received_data': data_content
        }
    except ClientDisconnect:
        raise HTTPException(status_code=status.HTTP_499_CLIENT_CLOSED_REQUEST, detail='客户端断开连接')
    except MaxBodySizeException as e:
        raise HTTPException(status_code=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE, 
                            detail=f'请求体大小超出限制:{e.body_len}字节')
    except streaming_form_data.exceptions.ValidationError:
        raise HTTPException(status_code=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE, 
                            detail='文件大小超出4GB限制')

关键说明

  • MemoryTarget基于BytesIO实现流式内存存储,适合处理大文件(需确保服务器内存足够)
  • 完整保留原有的大小验证逻辑,避免内存溢出风险
  • 解析完成后通过file_.value即可获取文件的字节数据,直接用于后续业务处理,全程无磁盘I/O

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 01:35:18