FastAPI实现文件上传下载

FastAPI实现文件上传下载


最近的项目需求,是前端vue,后端fastAPI,然后涉及到图像的消息发送,所以需要用fast写文件上传下载的接口,这里简单记录一下。

1.后端FastAPI

import os.path
import uvicorn
from fastapi import FastAPI, File, UploadFile
from fastapi.responses import FileResponse
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
app.add_middleware(# 解决跨域问题
    CORSMiddleware,
    allow_origins=["*"],  
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
#@app.get("/")#测试接口
#async def hello():
#   return {"ret": 'hello'}
@app.post("/uploadfile/")#前端上传的文件会放在文件目录下的uploaded_files目录下
async def create_upload_file(file: UploadFile = File(...)):
    print(file)
    if not os.path.exists('uploaded_files'):
        os.mkdir('uploaded_files')
    with open(f"uploaded_files/{file.filename}", "wb") as f:
        f.write(await file.read())
    return {"filename": file.filename}

@app.get("/downloadfile/{filename}")#前端会传递一个文件名,然后从后端文件目录的downloadfile目录下找到这个文件去下载
async def download_file(filename: str):
    directory_path = f"{os.path.dirname(__file__)}/downloadfile/"
    file_path = os.path.join(directory_path, filename)
    print(file_path)
    return FileResponse(file_path, media_type="application/octet-stream", filename=filename)
if __name__ == '__main__':
    uvicorn.run('upload:app', host='127.0.0.1', port=18005, reload=False)

2.后端html

我用postman测试后端没问题后,用html搞了一个简单的前端,实现这个功能,这里从后端下载文件到前端时需要前端给一个文件名,这个文件名一定要是后端/downloadfile/文件夹下的文件名,否则下载不到文件。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>文件上传与下载</title>
</head>
<body>

<h1>文件上传与下载d</h1>

<!-- 文件上传表单 -->
<form id="uploadForm" enctype="multipart/form-data">
    <input type="file" id="fileInput" name="file" accept=".txt">
    <button type="button" onclick="uploadFile()">上传</button>
</form>

<!-- 文件下载按钮 -->
<input type="text" id="fileNameInput" placeholder="输入后端downloadfile文件夹下的文件名">
<button onclick="downloadFile()">下载</button>


<script>
    async function uploadFile() {
        const fileInput = document.getElementById('fileInput');
        const file = fileInput.files[0];

        if (file) {
            const formData = new FormData();
            formData.append('file', file);

            try {
                const response = await fetch('http://127.0.0.1:18005/uploadfile/', {
                    method: 'POST',
                    body: formData
                });

                if (response.ok) {
                    alert('文件上传到后端upload_files目录下成功!');
                } else {
                    alert('文件上传失败.');
                }
            } catch (error) {
                console.error(error);
                alert('文件上传失.');
            }
        } else {
            alert('请选择需要上传的文件.');
        }
    }

    async function downloadFile() {
    // 获取输入框中的文件名
    const fileName = document.getElementById("fileNameInput").value;

    try {
        // 使用 fetch 请求下载文件
        const response = await fetch(`http://127.0.0.1:18005/downloadfile/${fileName}`);

        if (response.ok) {
            // 将文件转换为 Blob
            const blob = await response.blob();

            // 创建一个链接并设置下载属性
            const link = document.createElement('a');
            link.href = window.URL.createObjectURL(blob);
            link.download = fileName;

            // 模拟点击下载链接
            link.click();
        } else {
            alert('从后端downloadfile目录里下载此文件失败.');
        }
    } catch (error) {
        console.error(error);
        alert('下载文件出错.');
    }
}

</script>
</body>
</html>

3.效果

在这里插入图片描述

文本格式不能很好显示,请见谅(附件里有比较齐整的excel表格统计) 大小类型 传输类型 api方法 文件大小 花费时间 速率byte/ms 速率mb/s 缓存数组 次数 备注 大文件 下载 download_file(group_name, remote_filename, localFile) 1073741824(约1G) 28343ms 37883 36.12804413 无 1 下载 download_file(group_name, remote_filename , downloadStream) 1073741824(约1G) 29195ms 36778 35.07423401 0 1 fastDFS的DownloadStream,FileOutputStream 下载 download_file(group_name, remote_filename , downloadStream) 1073741824(约1G) 24352ms 44092 42.04940796 2K 1 fastDFS的DowloadStream,BufferedOutputStream 下载 download_file(group_name, remote_filename , DownloadCallback) 1073741824(约1G) 24831ms 43241 41.23783112 2K 1 实现DownloadCallback,BufferedOutputStream 下载 download_file(group_name, remote_filename , DownloadCallback) 1073741824(约1G) 25922ms 41422 39.50309753 8K 1 实现DownloadCallback,BufferedOutputStream 普通文件 下载 download_file(group_name, remote_filename, localFile) 59113472(约56M) 382ms 154747 147.5782394 无 1 下载 download_file(group_name, remote_filename , downloadStream) 59113472(约57M) 369ms 160199 152.7776718 0 1 fastDFS的DownloadStream,FileOutputStream 下载 download_file(group_name, remote_filename , downloadStream) 59113472(约58M) 499ms 118702 113.2030487 2K 1 fastDFS的DowloadStream,BufferedOutputStream 下载 download_file(group_name, remote_filename , DownloadCallback) 59113472(约59M) 592ms 99853 95.22724152 2K 1 实现DownloadCallback,BufferedOutputStream 下载建议:100M内数据使用fastDFS提供的DownloadStream;大于1G的数据,使用BufferedOutputStream和DowloadStream
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是小z呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值