主要内容

本页采用了机器翻译。点击此处可查看最新英文版本。

在打包的应用程序中包含和访问文件

R2026a

除了 MATLAB® 脚本文件之外,您还可以将其他类型的文件添加到可部署存档中,例如数据文件、DLL 和其他编程语言的文件。通过使用 which 函数或引用相对于可部署存档根目录 ctfroot 的文件位置从部署的代码中访问其他文件。

有关可部署存档的详细信息,请参阅关于可部署存档。

在可部署存档中包含文件

MATLAB Compiler™ 使用依赖关系分析函数来确定生成的包中包含的必要文件的列表。有关详细信息,请参阅使用 MATLAB Compiler 进行依赖关系分析。

您可以结合使用 -a 标志和 mcc 命令或 'AdditionalFiles' 选项和 compiler.build 函数(如 compiler.build.standaloneApplication)将其他文件包含在可部署存档中。

或者,您可以在编译器 App 中将文件添加到自定义需求部分。

使用 %#function Pragma 明确包含 MATLAB 数据文件

默认情况下,编译器在进行依赖关系分析时会将 MATLAB 数据文件(MAT 文件)排除在外。您可以通过手动添加来包含数据文件。

如果您希望编译器明确检查 MAT 文件中的数据,请在编写 MATLAB 代码时指定 %#function pragma。

例如,如果您想要包含对从 MAT 文件加载的 ClassificationSVM 类的依赖关系,请使用 %#function pragma。

function foo 
    %#function ClassificationSVM 
        load('svm-classifier.mat');
        num_dimensions = size(svm_model.PredictorNames, 2);
end %function foo

包含 MEX 文件、DLL 或共享库

当您编译包含 MEX 文件的 MATLAB 函数时,请确保依赖关系分析过程可以找到它们。特别是,请注意:

  • 由于依赖关系分析函数无法检查 MEX 文件、DLL 或共享库以确定它们的依赖关系,因此,应明确包含这些文件所需的所有可执行文件。

  • 如果您怀疑在依赖关系分析期间能否找到由 MEX 文件、DLL 或共享库调用的某个 MATLAB 函数,请手动包含该函数。

  • 并非所有函数都与编译器兼容。当编译完成后,请检查文件 mccExcludedFiles.log。该文件列出了从您无法部署的应用程序调用的所有函数。

从已部署函数访问文件

要从部署的 MATLAB 代码访问文件,请使用 isdeployed 检查代码是否在部署模式下运行。然后,使用 which 函数或指定相对于 ctfroot 的文件位置来找到该文件。

使用 which 函数

获取文件路径的最简单方法是,使用 which 函数来找到该文件。

if isdeployed
    locate_externapp = which('extern_app.exe');
end
如果文件 extern_app.exe 位于可部署存档内,则 which 函数返回其路径。

在 ctfroot 中指定文件位置

当您包含的文件位于当前 MATLAB 工作文件夹以外的文件夹中时,部分文件路径将保留在相对于 ctfroot 的可部署存档中。

  • 当前 MATLAB 工作文件夹或子文件夹中的文件保留从当前文件夹到文件的相对路径。

    例如,如果打包期间在 MATLAB 中打开的文件夹是 D:\Documents\Work\MyProj,则文件 D:\Documents\Work\MyProj\exfiles\data1.mat 将位于可部署存档中的 ctfroot\mfilename\exfiles\data1.mat 处,其中 mfilename 是主 MATLAB 脚本文件的名称,被截断为 12 个字符。

  • 当前文件夹之外的文件保留磁盘驱动器根目录的完整文件夹结构。

    例如,文件 C:\Users\mwuser\Documents\External\externdata\extern_app.exe 将位于可部署存档中的 ctfroot\Users\mwuser\Documents\External\externdata\extern_app.exe 处。

使用 fullfile 函数确保文件路径使用适合您系统的正确文件分隔符。

if isdeployed
    locate_data1 = fullfile(ctfroot,'exfiles','data1.mat');
    locate_data2 = fullfile(ctfroot,'Users','mwuser','Documents',...
        'External','externdata','extern_app.exe');
end

处理部署的应用程序的 MATLAB 数据的示例

以下示例说明将数据文件包含在打包的应用程序中,并使用 load 和 save 函数操作 MATLAB 数据。

  1. 导航到 MATLAB 中的工作文件夹。对于此示例,工作文件夹是 C:\Users\mwuser\Documents\Work\exfiles。

  2. 将 MATLAB 附带的 Data_Handling 和 externdata 文件夹复制到您的工作文件夹。

    copyfile(fullfile(matlabroot,'extern','examples','compiler','Data_Handling'),'Data_Handling');
    copyfile(fullfile(matlabroot,'extern','examples','compiler','externdata'),'externdata');

    在 MATLAB 命令提示符下,导航到您的工作文件夹中的新 Data_Handling 文件夹。

  3. 检查 ex_loadsave.m。

    ex_loadsave 脚本加载三个 MATLAB 数据文件,每个文件位于不同的文件夹中:

    • user_data.mat - 位于当前文件夹中

    • userdata\extra_data.mat - 位于当前文件夹的子文件夹中

    • ..\externdata\extern_data.mat - 位于当前文件夹之外

    function ex_loadsave
    % This example shows how to work with the "load/save" functions
    % on data files in deployed mode. This example contains three
    % source data files.
    %    user_data.mat 
    %    userdata/extra_data.mat 
    %    ../externdata/extern_data.mat
    %
    % Compile this example with mcc command: 
    %     mcc -m ex_loadsave.m -a 'user_data.mat'
    %         -a './userdata/extra_data.mat'
    %         -a '../externdata/extern_data.mat'
    %
    % In this example, the output data file is written to the path:
    %	output/saved_data.mat
    % relative to the application's run time current working directory.
    % When writing data files to local disk, do not save any files under $ctfroot,
    % as $ctfroot may be deleted and/or refreshed for each application run.
    %
    %==== load data file =============================
    if isdeployed
        % In deployed mode, all files in or under the main file's directory
        % may be loaded by full path, by path relative to ctfroot, or by
        % filename only, since their directories are on the MATLAB path.
        % Here we load 'user_data.mat' by full path.
        LOADFILENAME1=which(fullfile(ctfroot,mfilename,'user_data.mat'));    
        % These alternate methods also work:
        % LOADFILENAME1=which(fullfile(mfilename,'user_data.mat'));    
        % LOADFILENAME1=which(fullfile('user_data.mat'));
    
        % Here we load 'extra_data.mat' by relative path:
        LOADFILENAME2=which(fullfile('userdata','extra_data.mat'));
        % These alternate methods also work:
        % LOADFILENAME2=which(fullfile(ctfroot,'userdata','extra_data.mat'));
        % LOADFILENAME2=which(fullfile('extra_data.mat'));
    
        % For a data file external to the main MATLAB file's directory tree,
        % its full compile time path is appended to $ctfroot, so it is
        % best to simply load it by filename (since it is on the path):
        LOADFILENAME3=which(fullfile('extern_data.mat'));
    else
        %running the code in MATLAB
        LOADFILENAME1=fullfile(pwd,'user_data.mat');
        LOADFILENAME2=fullfile(pwd,'userdata','extra_data.mat');
        LOADFILENAME3=fullfile(pwd,'..','externdata','extern_data.mat');
    end
    
    % Load the data file from current working directory
    disp(['Load A from : ',LOADFILENAME1]);
    load(LOADFILENAME1,'data1');
    disp('A= ');
    disp(data1);
    
    % Load the data file from subdirectory
    disp(['Load B from : ',LOADFILENAME2]);
    load(LOADFILENAME2,'data2');
    disp('B= ');
    disp(data2);
    
    % Load extern data outside of current working directory
    disp(['Load extern data from : ',LOADFILENAME3]);
    load(LOADFILENAME3);
    disp('ext_data= ');
    disp(ext_data);
    
    %==== multiply two data matrices together ==============
    result = data1*data2;
    disp('A * B = ');
    disp(result);
    
    %==== save the new data to a new file ===========
    SAVEPATH=strcat(pwd,filesep,'output');
    if ( ~isdir(SAVEPATH))
        mkdir(SAVEPATH);
    end
    SAVEFILENAME=strcat(SAVEPATH,filesep,'saved_data.mat');
    disp(['Save the A * B result to : ',SAVEFILENAME]);
    save(SAVEFILENAME, 'result');
  4. 创建一个列出数据文件的元胞数组。

    datafiles = {'user_data.mat','./userdata/extra_data.mat','../externdata/extern_data.mat'};
  5. 使用 compiler.build.standaloneApplication 函数编译 ex_loadsave.m。

    compiler.build.standaloneApplication('ex_loadsave.m','AdditionalFiles',datafiles)
  6. 运行编译的应用程序。

    !ex_loadsavestandaloneApplication\ex_loadsave.exe
    Load A from : C:\Users\mwuser\AppData\Local\Temp\mwuser\mcrCache9.13\ex_loa0\ex_loadsave\user_data.mat 
    A=  
       21.4669   15.7255   15.6930   11.8122 
       19.6691   17.0570   17.4689   22.2803 
       20.3894   17.2548   17.3474   17.7316 
       19.3062   15.1321   16.0573   25.4584 
     
    Load B from : C:\Users\mwuser\AppData\Local\Temp\mwuser\mcrCache9.13\ex_loa0\ex_loadsave\userdata\extra_data.mat 
    B=  
       15.3970   20.5682   13.8388   26.5186 
       14.2255   24.6506   18.9545   24.8117 
       14.9904   22.8211   16.4942   25.3533 
       13.1022   26.0567   21.2197   24.8940 
     
    Load extern data from : C:\Users\mwuser\AppData\Local\Temp\mwuser\mcrCache9.13\ex_loa0\Users\mwuser\Documents\Work\exfiles\externdata\extern_data.mat 
    ext_data=  
       27.6923   69.4829   43.8744   18.6873 
        4.6171   31.7099   38.1558   48.9764 
        9.7132   95.0222   76.5517   44.5586 
       82.3458    3.4446   79.5200   64.6313 
     
    A * B =  
       1.0e+03 * 
     
        0.9442    1.4951    1.1046    1.6514 
        1.0993    1.8042    1.3564    1.9424 
        1.0518    1.7026    1.2716    1.8500 
        1.0868    1.7999    1.3591    1.9283 
     
    Save the A * B result to : C:\Users\mwuser\Documents\Work\exfiles\Data_Handling\output\saved_data.mat
  7. 将结果与 ex_loadsave.m 的输出进行比较。

另请参阅

|

主题