如何处理文件并返回给前端

一、概述

打开客户端浏览器下载文件是比较常见的功能,那么后端是如何处理文件的呢?大体解决方法是后端会将文件处理成字节流并返回前端。那么在浏览器访问接口即可自动下载文件(此处是GET请求)。一篇关于文件流的文章值得了解

二、FastApi

2.1、下载:

from starlette.responses import StreamingResponse
from fastapi.response import FileResponse, Response

@app.get("/file")
def file():
	# 提供一个下载成功后的文件名字
    fileName = "xxx.jpg"
    StreamingHttpResponse将文件内容进行流式传输,数据量大可以用这个方法
    response = StreamingResponse(get_file_byte("xxx.jpg"), media_type="application/octet-stream")
    # 在请求头进行配置
    response = response.headers["Content-Disposition"] = "attachment; filename=%s"%fileName
    return response

def get_file_byte(filename, chunk_size=512):  # filename可以是文件,也可以是压缩包
    with open(filename, "rb") as f:
        while True:
            content = f.read(chunk_size)
            if content:
                yield content
            else:
                break

三、django

3.1、下载

import os
from rest_framework import status
from django.http import HttpResponse
from rest_framework.response import Response
from django.utils.encoding import escape_uri_path

@action(methods=['GET'], detail=False)
def download_files(self, request, *args, **kwargs):
	# fiName = request.query_params.get("file_name")  # 辅助参数(?后)数据提取方式
	fileName = request.data["file_name"]  # 请求体body数据请求方式
	base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  # 项目根目录
    file_path = os.path.join(base_dir, 'upload','images', fileName)  # 下载文件的绝对路径
	
	try:
		# 提供一个下载成功后的文件名字
		fileName = "xxx.zip"
        response = HttpResponse(content = file_iterator(file_path))  # 字节流数据
		response["content-type"] = "application/octet-stream"
		response["Content-Disposition"] = "attachment; filename='{}'".format(escape_uri_path(fileName))
    except:
        return Response({"code":status.HTTP_400_BAD_REQUEST, "msg":"失败", "error": "Sorry but Not Found the File"})

    return response

def file_iterator(file_path, chunk_size=512):
        """
        文件生成器,防止文件过大,导致内存溢出
        :param file_path: 文件绝对路径
        :param chunk_size: 块大小
        :return: 生成器
        """
        with open(file_path, mode='rb') as f:
            while True:
                c = f.read(chunk_size)
                if c:
                    yield c
                else:
                    break

3.2、上传

import os
from rest_framework.response import Response

@action(methods=['POST'], detail=False)
def upload_file(self, request, *args, **kwargs):
	try:
		# 接收数据并处理
		data = request.data
		# 文件上传名字、文件上传路径、文件对象
		name, path, fileObj= data["name"], data["path"], request.FILES["file"]
		# 将传递的文件处理为文件流,进行保存
		file = b''
		for byteData in fileObj.chunks():
			file += byteData
		# 写入本地服务器
		baseDir = os.path.dirname(os.path.abspath(__name__));  # 项目根目录
	    jpgDir = os.path.join(baseDir,'static','jpg');   #  文件保存路径
	    fileName = os.path.join(jpgDir, name);
		
		with open(fileName, "wb") as f:
			f.write(file)
	except:
		return Response({"code":status.HTTP_400_BAD_REQUEST, "msg":"失败", "error": "Uploading files failed. Procedure"})
	return Response({"code":status.HTTP_200_OK, "msg":"成功")
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

学无止境gwx

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

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

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

打赏作者

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

抵扣说明:

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

余额充值