Fastapi上传的文件未保存



我是fastapi的初学者。我试图保存从前端上传的zip文件

from fastapi import FastAPI, File, UploadFile
import os
import zipfile
import shutil
app = FastAPI() 

@app.post('/FileUpload/')
def FileUpload(file: UploadFile = File(...)):
dest=os.path.dirname(os.path.dirname( os.path.abspath(__file__))) +f'FILES{file.filename}'   
if zipfile.is_zipfile(file.file):   
try:            
with open(dest, "wb+") as file_object:
shutil.copyfileobj(file.file, file_object)
finally:
file.file.close()
else:
print("Invalid File type")
return {"Status": True}

当前文件夹中只保存同名的1KB文件,不保存上传文件。我在这里错过了什么或者这种方法有什么问题吗?

感谢你的帮助,提前谢谢你。

尽管在这种情况下这不是问题,但我强烈建议使用pathlib.Path()来定义上传的目的地

这个问题似乎与zipfile.is_zipfile()有关。尽管文档没有明确说明这一点,但该函数显然是"扫描"的。整个文件并在最后留下流(不确定这是一个bug还是一个特性)。同时,shutil.copyfileobj()文档告诉我们:

[…注意,如果fsrc对象的当前文件位置不为0,则只复制从当前文件位置到文件末尾的内容。

为了更好地理解发生了什么,您可以在代码的不同位置添加一个.tell()

要解决这个问题,您可以使用.seek(0)重置流位置:

from pathlib import Path
from fastapi import FastAPI, File, UploadFile
import zipfile
import shutil
app = FastAPI()
@app.post('/FileUpload/')
def FileUpload(file: UploadFile = File(...)):
dest = Path(__file__).resolve().parents[1] / "FILES" / file.filename
#          ^^^^
#          Not directly related to your problem but more elegant imho.
print(file.file.tell())
# 0  <- stream position is at the beginning
if zipfile.is_zipfile(file.file):   
print(file.file.tell())
# <file size in bytes>  <- stream position is at the end
# Reset the file stream:
file.file.seek(0)
print(file.file.tell())
# 0  <- stream position is back at the beginning
try:
with open(dest, "wb+") as file_object:
shutil.copyfileobj(file.file, file_object)
finally:
file.file.close()
else:
print("Invalid File type")
return {"Status": True}

最新更新