Fastapi 上传文件未保存
Fastapi uploaded file not saved
我是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()
. Even though the documentation doesn't specify this, the function apparently "scans" the whole file and leaves the stream at the end (not sure whether this is a bug or a feature). At the same time, the shutil.copyfileobj()
docs有关告诉我们:
[...] Note that if the current file position of the fsrc object is not 0, only the contents from the current file position to the end of the file will be copied.
为了更好地理解发生了什么,您可以在代码的不同位置添加一个 .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}
我是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()
. Even though the documentation doesn't specify this, the function apparently "scans" the whole file and leaves the stream at the end (not sure whether this is a bug or a feature). At the same time, the shutil.copyfileobj()
docs有关告诉我们:
[...] Note that if the current file position of the fsrc object is not 0, only the contents from the current file position to the end of the file will be copied.
为了更好地理解发生了什么,您可以在代码的不同位置添加一个 .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}