Flask使用send_file出现FileNotFoundError的问题排查与解决
Flask中send_file报FileNotFoundError但文件已存在的问题解决
问题情况
使用Flask的send_file接口下载生成的CSV文件时,明明文件已成功创建(控制台打印Path exists: True),但仍触发FileNotFoundError。尝试过管理员模式运行VSCode、改用send_from_directory均无效,需要实现点击链接即可下载CSV的功能。
相关代码
前端模板代码
<p><a href="{{ url_for('views.download_csv', semester_name=semester.semester_name) }}">Download CSV File</a></p>
后端处理代码
distribution_df = pd.DataFrame(distribution_dict) file_name = f'{semester.semester_name}_grade_distributions_{str(datetime.now())}.csv' file_name = secure_filename(file_name) output_dir = 'output' if not os.path.exists(output_dir): os.makedirs(output_dir) path = f'{output_dir}/{file_name}' distribution_df.to_csv(path , index=False) print("Checking path:", path) print("Path exists:", os.path.exists(path)) return send_file(path)
原因分析及解决方法
相对路径解析错误:Flask运行时的工作目录可能和你预期的项目根目录不一致,导致
send_file无法找到相对路径下的文件。
解决:改用绝对路径构建文件路径,两种可靠方式:# 方式1:通过os.path生成绝对路径 import os path = os.path.abspath(os.path.join(output_dir, file_name)) # 方式2:结合Flask应用的根路径 from flask import current_app path = os.path.join(current_app.root_path, output_dir, file_name)send_file参数缺失:默认配置下可能因文件类型识别或缓存问题导致报错,添加
as_attachment=True强制触发下载,并指定download_name确保文件名正确:return send_file(path, as_attachment=True, download_name=file_name)文件名含特殊字符:
datetime.now()直接转字符串会包含冒号,虽然secure_filename会替换,但仍可能引发系统兼容问题,建议格式化时间为无特殊字符的格式:from datetime import datetime # 格式化为YYYYMMDDHHMMSS,避免特殊字符 file_name = f'{semester.semester_name}_grade_distributions_{datetime.now().strftime("%Y%m%d%H%M%S")}.csv'send_from_directory正确用法:如果改用该方法,必须传入目录的绝对路径和文件名:
from flask import send_from_directory output_dir_abspath = os.path.abspath(output_dir) return send_from_directory(output_dir_abspath, file_name, as_attachment=True)
内容的提问来源于stack exchange,提问作者Tahmid Ali
相关产品推荐
相关产品推荐

