如何修改基于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
相关产品推荐
相关产品推荐

