我是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}