You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Discord机器人Matplotlib生成Base64过长引发OSError问题求助

解决OSError: [Errno 36] File name too long问题

问题根源

你调用send_file(data[short_url], mimetype='image/png')时,data[short_url]是Base64编码的字符串,但Flask的send_file默认会把字符串参数当作文件路径处理,导致它尝试打开一个长度远超系统限制的文件名,触发错误。

修复方案

把Base64字符串解码为字节流,用io.BytesIO包装后传给send_file,让Flask识别为内存中的文件内容:

修改redirect_to_chart函数:

import base64
import io
from flask import send_file

@app.route("/api/url/<short_url>.png")
def redirect_to_chart(short_url):
    with open("urls.json", "r") as f:
      data = json.load(f)
    if short_url in data:
        # 解码Base64为字节,包装成BytesIO对象
        chart_bytes = io.BytesIO(base64.b64decode(data[short_url]))
        # 设置文件指针回到开头
        chart_bytes.seek(0)
        # 传给send_file,可指定下载文件名
        return send_file(chart_bytes, mimetype='image/png', download_name=f"{short_url}.png")

    return "Error"

额外优化建议

  • 避免存储Base64字符串:Base64编码会让文件体积增加约33%,建议直接将Matplotlib生成的字节流保存为本地文件(比如charts/{short_url}.png),然后在urls.json中存储文件路径而非Base64。这样既节省存储,也能让send_file直接读取本地文件,性能更好:
    # 在bcrt函数中替换Base64存储部分
    import os
    # 确保charts目录存在
    os.makedirs("charts", exist_ok=True)
    chart_path = f"charts/{short_url}.png"
    with open(chart_path, "wb") as f:
        f.write(chart_bytes.getvalue())
    # 存储路径到json
    data[short_url] = chart_path
    
    # 在redirect_to_chart中直接传路径
    return send_file(data[short_url], mimetype='image/png')
    
  • 清理过期文件:如果短链接有过期需求,定期清理charts目录中的旧文件和urls.json中的过期条目,避免存储冗余。

内容的提问来源于stack exchange,提问作者yeet2675

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 03:32:51