Flask应用使用tempfile生成下载文件时出现FileNotFoundError问题
问题原因分析
- 你使用的
tempfile.TemporaryFile在类Unix系统(macOS、Linux)下创建的文件默认不会在文件系统保留可见的名称入口,调用.name属性拿到的并非有效的磁盘访问路径,而且你传入的suffix等命名参数也不会生效,这就是报错里路径后缀丢失、仅显示数字/Desktop/bulk_final/10的原因。 - Flask的
send_file不会立即读取文件内容,它会将文件路径/对象交给WSGI服务层后续处理,此时with上下文已经执行结束,临时文件会被自动销毁,就算路径有效也会找不到文件。
解决方案
你可以根据文件大小选择以下任意一种方案:
方案1:使用命名临时文件(适合大文件)
改用tempfile.NamedTemporaryFile关闭自动删除逻辑,响应返回后手动清理文件:
import tempfile import csv import os # 你的路由函数内 csvfilenew = tempfile.NamedTemporaryFile(mode='w', newline="", dir=".", suffix='.csv', delete=False, encoding='utf-8-sig') try: writer = csv.writer(csvfilenew, delimiter= ';') myClick() # 写完后将文件指针移到开头 csvfilenew.seek(0) return send_file( csvfilenew, as_attachment=True, # Flask2.0以下版本把download_name换成attachment_filename download_name='cleanfile.csv', mimetype='text/csv' ) finally: # 响应处理完成后删除临时文件 csvfilenew.close() os.unlink(csvfilenew.name)
方案2:内存生成文件(适合小文件,效率更高)
不需要落地磁盘,直接在内存中生成CSV内容返回:
from io import StringIO import csv from flask import send_file # 你的路由函数内 output = StringIO() writer = csv.writer(output, delimiter=';') myClick() output.seek(0) return send_file( output, as_attachment=True, download_name='cleanfile.csv', mimetype='text/csv' )
内容的提问来源于stack exchange,提问作者airn
相关产品推荐
相关产品推荐

