FastApi-15-文件上传-3

简介: FastApi-15-文件上传-3

文件保存


前面我们已经学习了文件的上传,多个文件上传,以及文件对象的常用属性获取。但是实际开发中通常需要在上传文件后对文件进行保存,今天我们就一起来看看。


代码


from fastapi import File,UploadFile
from typing import List
@app.post('/upfile1/')
async def up_f1(request:Request,upload_list:List[UploadFile]=File(...)):
    # 获取文件名称列表
    file_names=[dd.filename for dd in upload_list]
    # 获取文件大小列表
    file_sizes=[len(ds.read())/1024 for ds in [dd.file for dd in upload_list]]
    # 获取文件类型列表
    file_types=[dd.content_type for dd in upload_list]
    # 获取文件对象列表
    filesss = [dd for dd in upload_list]
    # 根据文件个数进行遍历,使用列表索引
    for ss in range(len(file_names)):
        # 指定文件保存路径(使用源文件名称),当前路径下的file目录下
        pth = 'file\\{}'.format(file_names[ss])
        # 读取文件对象内容,阻塞,等待文件上传完成
        fx = await filesss[ss].read()
        # 根据文件路径打开,保存文件
        with open(pth,'wb') as f:
            f.write(fx)
    return templates.TemplateResponse(
        'f.html',
        {
            "request":request,
            "file_names":file_names,
            "file_sizes":file_sizes,
            "file_types":file_types
            })
复制代码


执行上传


选择两个文件进行上传


网络异常,图片无法展示
|


查看当前路径下的 file 目录

网络异常,图片无法展示
|


可以看到,文件已经上传成功。


Q&A


Q:对于超大文件应该如何处理呢?


明显的,上面的代码对于超大文件的处理已经显得力不从心了,具体时间为什么呢?因为文件对象的 read 方法是将前端传过来的文件读到内存中,如果是很大的文件就会将内存撑爆。


就算你的服务器内存够大,那也会存在这个问题。而且成本很高。再或者你限制上传文件的大小,那对当前的内存也是亚历山大,而且可能会影响其他服务的运行。

最优的解决方案就是分片读取,分片保存。


代码

@app.post('/upfile1/')
async def up_f1(request:Request,upload_list:List[UploadFile]=File(...)):
    # 获取文件名称列表
    file_names=[dd.filename for dd in upload_list]
    # 获取文件大小列表
    file_sizes=[round(len(ds.read())/1024,2) for ds in [dd.file for dd in upload_list]]
    # 获取文件类型列表
    file_types=[dd.content_type for dd in upload_list]
    # 获取文件对象列表
    filesss = [dd for dd in upload_list]
    # 根据文件个数进行遍历,使用列表索引
    for ss in range(len(file_names)):
        # 指定文件保存路径(使用源文件名称),当前路径下的file目录下
        pth = 'file\\{}'.format(file_names[ss])
        with open(pth, 'wb') as f:
            # @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
            # 每次读取1Mb写入
            for i in iter(lambda : filesss[ss].file.read(1024*1024),b''):
                f.write(i)
            # @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    return templates.TemplateResponse(
        'f.html',
        {
            "request":request,
            "file_names":file_names,
            "file_sizes":file_sizes,
            "file_types":file_types
            })
复制代码


如上代码中的@@@@@@区域,每次读取 1Mb,写入文件,即可实现分块读取上传。


效果


网络异常,图片无法展示
|


网络异常,图片无法展示
|


感谢您的阅读,别忘了关注,点赞,评论,转发四连哟!

相关文章
|
4月前
|
人工智能 移动开发 小程序
uniapp框架——vue3+uniFilePicker+fastapi实现文件上传(搭建ai项目第二步)
uniapp框架——vue3+uniFilePicker+fastapi实现文件上传(搭建ai项目第二步)
255 2
|
NoSQL 测试技术 Redis
FastAPI(八十四)实战开发《在线课程学习系统》--接口测试(下)
FastAPI(八十四)实战开发《在线课程学习系统》--接口测试(下)
FastAPI(八十四)实战开发《在线课程学习系统》--接口测试(下)
|
存储 测试技术 数据安全/隐私保护
FastAPI(八十三)实战开发《在线课程学习系统》--注册接口单元测试
FastAPI(八十三)实战开发《在线课程学习系统》--注册接口单元测试
FastAPI(八十三)实战开发《在线课程学习系统》--注册接口单元测试
|
测试技术 数据安全/隐私保护
FastAPI(八十四)实战开发《在线课程学习系统》--接口测试(上)
FastAPI(八十四)实战开发《在线课程学习系统》--接口测试(上)
FastAPI(八十二)实战开发《在线课程学习系统》接口开发-- 课程上架下架
FastAPI(八十二)实战开发《在线课程学习系统》接口开发-- 课程上架下架
|
NoSQL Redis 数据库
FastAPI(八十一)实战开发《在线课程学习系统》接口开发-- 推荐课程列表与课程点赞
FastAPI(八十一)实战开发《在线课程学习系统》接口开发-- 推荐课程列表与课程点赞
FastAPI(八十)实战开发《在线课程学习系统》接口开发-- 课程列表
FastAPI(八十)实战开发《在线课程学习系统》接口开发-- 课程列表
FastAPI(七十九)实战开发《在线课程学习系统》接口开发-- 加入课程和退出课程
FastAPI(七十九)实战开发《在线课程学习系统》接口开发-- 加入课程和退出课程