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

如何通过Dash上传FMU文件并获取可被函数识别的文件路径

问题描述
  • 需求:允许用户上传FMU文件(可视为压缩文件夹),并传递给仅接受文件路径字符串的函数load_fmu使用。
  • 限制条件:
    1. load_fmu仅支持文件路径字符串作为输入,不接受字节流、内存对象等其他类型。
    2. Dash的Upload组件出于安全考虑,仅返回文件名,不返回用户本地的文件路径,且该文件名无法被load_fmu识别。
  • 核心疑问:如何加载FMU这类不支持decode方法的文件?能否获取Upload组件存入内存的文件的路径字符串供load_fmu访问?
解决方案

由于load_fmu必须依赖真实的文件系统路径才能工作,而Upload组件仅提供文件的base64编码内容,唯一可行的方案是将上传的字节内容写入服务器本地的临时文件,再将临时文件的路径传给load_fmu。具体步骤:

  1. 解码Upload组件传来的base64字符串,得到文件的字节流。
  2. 在服务器本地创建带.fmu后缀的临时文件,将字节流写入该文件。
  3. 把临时文件的完整路径作为参数传入load_fmu。
  4. 加载完成后可删除临时文件,避免占用服务器磁盘空间。
修改后的可运行代码
from pyfmi import load_fmu
from dash import Dash, dcc, html, Input, Output, State, callback
import base64
import tempfile
import os

app = Dash(__name__)

app.layout = html.Div([
    dcc.Upload(
        id='upload-fmu',
        children=html.Div([
            '拖拽或 ',
            html.A('选择FMU文件')
        ]),
        style={
            'width': '10%',
            'height': '40px',
            'lineHeight': '60px',
            'borderWidth': '1px',
            'borderStyle': 'dashed',
            'borderRadius': '5px',
            'textAlign': 'center',
            'margin': '10px'
        },
        multiple=True
    ),
    html.Div(id='output-fmu-upload'),
])
     
def parse_contents(contents, filename, date):
    content_type, content_string = contents.split(',')
    decoded = base64.b64decode(content_string)
    
    try:
        if filename.endswith('.fmu'):
            # 创建临时文件,保留.fmu后缀确保格式被识别
            with tempfile.NamedTemporaryFile(delete=False, suffix='.fmu') as tmp_file:
                tmp_file.write(decoded)
                tmp_file_path = tmp_file.name
            
            # 通过临时文件路径加载FMU模型
            model = load_fmu(tmp_file_path)
            print(f"成功加载模型:{model.get_name()}")
            
            # 使用完毕后删除临时文件,释放磁盘空间
            os.unlink(tmp_file_path)
            
            return html.Div([
                html.H5(f"文件 {filename} 加载成功"),
                html.P(f"模型名称:{model.get_name()}"),
                html.P(f"上传时间:{date}")
            ])
    except Exception as e:
        print(f"错误详情:{str(e)}")
        return html.Div([
            f"处理文件 {filename} 时出错:{str(e)}"
        ])

@callback(Output('output-fmu-upload', 'children'),
          Input('upload-fmu', 'contents'),
          State('upload-fmu', 'filename'),
          State('upload-fmu', 'last_modified'))
def update_output(list_of_contents, list_of_names, list_of_dates):
    if list_of_contents is not None:
        children = [
            parse_contents(c, n, d) for c, n, d in
            zip(list_of_contents, list_of_names, list_of_dates)]
        return children

if __name__ == '__main__':
    app.run(debug=True)
关键注意事项
  • 必须使用真实文件路径:load_fmu底层依赖文件系统操作,无法直接读取内存中的字节流(如io.BytesIO对象),因此写入临时文件是唯一可行方案。
  • 临时文件管理:使用delete=False确保文件在关闭后不会被自动删除,让load_fmu能正常访问;加载完成后通过os.unlink删除临时文件,避免磁盘占用。如果需要保留文件用于后续操作,可以移除删除逻辑,或添加定期清理机制。
  • 文件后缀:创建临时文件时指定suffix='.fmu',确保load_fmu能正确识别文件格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 08:17:45