MATLAB编程与应用系列-第16章 外部接口技术(3)

本章教程共分为7篇进行阐述:
MATLAB编程与应用系列-第16章 外部接口技术(1)
MATLAB编程与应用系列-第16章 外部接口技术(2)
MATLAB编程与应用系列-第16章 外部接口技术(3)
MATLAB编程与应用系列-第16章 外部接口技术(4)
MATLAB编程与应用系列-第16章 外部接口技术(5)
MATLAB编程与应用系列-第16章 外部接口技术(6)
MATLAB编程与应用系列-第16章 外部接口技术(7)

本系列教程来源于出版书籍《基于MATLAB编程基础与典型应用书籍》,如涉及版权问题,请联系:156204968@qq.com。 出版社:人民邮电出版社, 页数:525。

本系列教程目前基于MATLABR2006a,可能对于更高级版本的功能和函数有差异,教程中如有问题,请联系:156204968@qq.com

16.3 MAT文件应用

MAT文件是MATLAB开发环境存储数据的一种特殊的数据格式,使用MAT数据文件可以在不同的开发平台下进行数据交换和通信,可以在独立MATLAB应用程序中导出和读入数据文件。MATLAB应用程序接口(API)函数库提供了使用C,C++和FORTRAN等语言编写的MAT函数库,通过调用MAT函数库,MEX函数库以及MX函数库相关函数,可以非常轻松地编写MEX文件读入和导出MAT格式的数据文件。

�###16.3.1 MATLAB数据导入导出方式
在MATLAB开发环境下,可以通过多种不同的手段向MATLAB开发环境中导入数据或者从MATLAB开发环境中向其他开发平台导出数据。

1. 向MATLAB开发环境中导入数据

可以通过以下不同的方式向MATLAB开发环境中导入数据,但是对于不同的情况,比如数据规模的大小,开发平台的外部需求等,读者可以选择其中最方便的某一种导入数据方式:

  • 使用命令行导入数据
    这种方法适合与当导入的数据规模比较小,那么可以直接在MATLAB命令行窗口中导入数据。例如:
>> a = rand(3)
a =

    0.9501    0.4860    0.4565
    0.2311    0.8913    0.0185
    0.6068    0.7621    0.8214
>> assignin('base','T',a)   //在应用程序中将a变量赋值给变量T
  • 创建数据输入的M文件
    很明显,这种数据导入方式仅仅适合与当数据文件还不存在与工作环境下,需要人工输入数据文件时,采用这种方式比较方便。或者从其他环境比如TEXT文件,EXCEL文件中导入数据文件。

  • 使用load命令导入数据文件
    同save命令相对,当数据变量存在与MATLAB工作环境下时,可以使用save命令将数据变量存储为MAT数据文件格式。那么使用load命令就可以直接向Workspace中导入数据文件。

  • 使用MATLAB的I/O函数读取数据文件
    使用MATLAB的I/O函数fopen, fread以及其他的一些I/O读写函数读入其他平台下的数据文件格式。

  • 编写MEX文件读入MAT数据
    通过MATLAB应用程序接口(API)的MEX函数库,MX函数库和MAT函数库,编写MEX文件读入MAT数据文件。在本节的实例演示中将提供一个标准的MEX文件读入MAT数据的程序代码。

2. 从MATLAB环境中导出数据

同向MATLAB环境导入数据相仿,从MATLAB环境中导出数据也有相对应的一些方式可以供读者进行选择参考。

  • 创建DIARY文件
    通过使用MATLAB命令行diary来创建当前工作窗口中输入和输出结果文本,可以通过文本编辑器或者使用MATLAB函数open命令打开diary文件查看当前输入的数据和输出结果。使用diary on和diary off命令来启动和关闭记录。当在命令行窗口中输入diary on命令后,那么从该条命令开始,将在diary文件中进行记录,直到输入diary off命令结束输入输出的记录。
  • 使用save命令存储数据文件
    MATLAB使用save命令存储数据文件,可以使用save file.dat variableName –ascii命令将数据文件以ASCII文件存储威为.dat文件。例如:
>> a = rand(3);
>> save fileName.dat a -ascii
>> load fileName.dat
  5.2515250e-001  8.3811845e-001  3.7948102e-001
  2.0264736e-001  1.9639514e-002  8.3179602e-001
  6.7213747e-001  6.8127716e-001  5.0281288e-001
  • 使用MATLAB的I/O函数写入数据
    使用MATLAB的I/O函数fopen, fwrite等函数可以将MATLAB环境下的数据存储为其他开发平台所需要的数据文件格式。

  • 创建MEX文件写MATLAB环境数据
    同读入数据一样,可以使用MATLAB应用程序接口(API)函数库MAT函数库,MEX函数库和MX函数库写出MATLAB环境数据。在本节中也提供了一个标准的创建MEX文件写数据的程序代码。

16.3.2 MAT函数库函数

使用MATLAB命令行save命令可以将MATLAB工作环境中的数据存储为MAT数据文件格式。在其他开发平台,需要使用MATLAB应用程序接口来读入和写出MAT数据文件中的数据变量。在MEX一节中,已经介绍了MATLAB应用程序接口(API)函数库的MEX函数库和MX函数库相关函数,在读写MAT文件时,同样需要使用到MEX函数库和MX函数库。本节中主要简单介绍MAT函数库相关函数的功能描述,在下一小节中,将通过实例演示如何使用MATLAB应用程序接口(API)进行MAT文件的读写。

表16.4所示为C语言常用MAT函数库函数

MAT函数 功能描述
matOpen 打开MAT文件
matClose 关闭MAT文件
matGetDir 从MAT文件中获取变量列表
matGetVariable 从MAT文件中读入变量
matPutVariable 向MAT文件中写入变量
matGetNextVariable 从MAT文件中读入下一个变量
matDeleteVariable 从MAT文件中删除变量

16.3.3 Mex文件读写MAT文件

在了解MAT文件基本概念和MATLAB应用程序接口(API)函数库常用MAT函数库函数后。在本小节,将通过两个实例matCDemo.c文件和matMexLoadDemo分别演示使用MATLAB应用程序接口(API)函数库函数读写MAT文件。编写以下matCDemo.c文件,可以实现写入MATLAB数据到MAT文件中的功能。

/*  
 *  matCDemo.c
*/
#include "mex.h"
#include "mat.h"

void mexFunction(int nlhs, mxArray *plhs[],
                                int nrhs, const mxArray *prhs[])
{
    //初始变量定义,包括数组和mxArray数据结构定义
    mxArray *pString, *pArray1, *pArray2;
    double a1[] = {0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0};
    double a2[] = {9.0, 4.0,5.4,6.4,3.2,1.5};
    //MATFile文件定义和文件名定义
    char *filename;
    MATFile *file;
    int flag, buflen;
    
    //输入个数检测数据
    if (nrhs != 1)
        mexErrMsgTxt("Error: One intput parameter is required to represent the file name!");
    if (nrhs > 1)
        mexErrMsgTxt("Error: No more than one input parameter.");
    
    //输入参数类型检测,输入必须为字符串类型。
    if ( mxIsChar(prhs[0]) != 1)
        mexErrMsgTxt("Error: Input must be string!");
    if ( mxGetM(prhs[0]) != 1)
        mexErrMsgTxt("Error: Input must be a row vector!");
    //创建字符串和错误检测
    pString = mxCreateString("This is the MAT demo in C lanuage! Enojy it~!");
    if (pString == NULL)
        mexErrMsgTxt("Error: Cannot create string!");
    //创建mxArray参数矩阵初始大小
    pArray1 = mxCreateDoubleMatrix(3,3,mxREAL);
    pArray2 = mxCreateDoubleMatrix(2,3,mxREAL);
    if( (pArray1 == NULL)||(pArray2 ==NULL) )
        mexErrMsgTxt("Error: Cannot create the double matrix!");
    //将定义的数组拷贝给mxArray变量
    memcpy( (void *)(mxGetPr(pArray1)), (void *)a1, sizeof(a1));
    memcpy( (void *)(mxGetPr(pArray2)), (void *)a2, sizeof(a2));
    
    //获取文件名称
    buflen = (mxGetM(prhs[0]) * mxGetN(prhs[0])) + 1;
    //申请建立字符串大小的内存空间
    filename = mxCalloc(buflen,sizeof(char));
    flag = mxGetString(prhs[0], filename, buflen);
    if( flag != 0)
        mexWarnMsgTxt("Not enough memory space!");
    
    //创建新的MAT文件
    file = matOpen(filename,"w");
    if ( file = NULL )
        mexWarnMsgTxt("Error: Cannot create the mat file!");

    //向MAT文件中写入数据
    matPutVariable(file, "variableString", pString);
    matPutVariable(file, "variableDoubleMatrix1", pArray1);
    matPutVariable(file, "variableDoubleMatrix2", pArray2);
    
    //关闭MAT文件
    matClose(file);
    
    //释放内存空间
    mxDestroyArray(pString);
    mxDestroyArray(pArray1);
    mxDestroyArray(pArray2);
    
    mxFree(filename);
    
}

使用mex命令编译该文件,在Matlab命令行窗口中调用该函数:

>> matcDemo('matfile.mat')

通过which命令查看matfile文件是否已经建立:

>> which matfile.mat
C:\Program Files\MATLAB\R2006a\work\matfile.mat
在命令行窗口中使用load命令可以查看matfile.mat数据文件的内容:
>> load matfile.mat
>> whos
  Name                        Size                    Bytes  Class

  variableDoubleMatrix1       3x3                        72  double array
  variableDoubleMatrix2       2x3                        48  double array
  variableString              1x45                       90  char array

Grand total is 60 elements using 210 bytes

在该实例中,演示了使用MEX文件写MAT数据文件,基本的编写程序步骤包括:首先定义mxArray数据结构变量,进行输入输出参数个数和类型的检测,使用mxCreate前缀函数创建mxArray数据结构变量的初始值,将定义的数组拷贝给mxArray变量,然后matOpen函数打开MAT文件,使用matPutVariable函数向MAT文件写入数据,matClose函数关闭MAT文件,释放定义存储mxArray数据变量的内存空间。以下matMexLoadDemo.c程序则实现读入MAT文件数据的功能,编写程序的步骤和写入MAT文件数据刚好相反,程序代码如下:

/*
 *  matMexLoadDemo.c
 */

#include <string.h>
#include "mex.h"
#include "mat.h"
const int MAXSIZE = 100;
void mexFunction(int nlhs, mxArray *plhs[],
                                int nrhs, const mxArray *prhs[])
{
    //MATFile文件定义和相关变量定义
    MATFile *file;
    char *fileName;
    char *variableName[MAXSIZE];
    int counter,buf_len,index;
    mxArray *variableValue = NULL;
    // 给函数文件名分配内存空间并获取文件名
    buf_len = mxGetN(prhs[0]) + 1;
    fileName = (char *) mxCalloc(buf_len, sizeof (char));
    mxGetString(prhs[0], fileName, buf_len);
    //读取MAT文件函数名
    counter = 0;
    for( index = 1; index < nrhs; index ++ )
    {
        int variableLength = mxGetN(prhs[index]) + 1;
        variableName[ counter ] = (char *)mxCalloc(variableLength, sizeof (char));
        mxGetString(prhs[index], variableName[counter],variableLength);
        counter ++;
    }
    // 打开MAT文件
    file = matOpen(fileName, "r");
    if ( file < (MATFile *) 3 )
    {
        mexErrMsgTxt("Error: Cannot open the mat file!");
    }
    //读取MAT文件变量
    if (counter > 0)
    {
        for ( index = 0; index < counter; index ++)
        {
            variableValue = matGetVariable(file, variableName[index]);
            mexPutVariable("Caller",variableName[index], variableValue);
            
            mxFree(variableName[index]);
        }
    }
    else
    {
        const char *var_name;
        while((variableValue=matGetNextVariable(file, &var_name))!=NULL) 
        {
            mexPutVariable("caller", var_name, variableValue);
        }
    }
    //关闭MAT文件
    matClose(file);
    mxFree(fileName);
}

使用mex命令编译matMexLoadDemo.c文件,在MATLAB命令行窗口中输入:

>> mex matMexLoadDemo.c

通过调用matMexLoadDemo编译文件,就可以读入mat数据文件的数据:

>> matMexLoadDemo('matfile.mat')
>> whos
  Name                        Size                    Bytes  Class

  variableDoubleMatrix1       3x3                        72  double array
  variableDoubleMatrix2       2x3                        48  double array
  variableString              1x45                       90  char array

Grand total is 60 elements using 210 bytes

以上通过两个实例分别演示了使用MATLAB应用程序接口(API)函数库函数,编写MEX文件以实现MAT数据文件的写入和读出。16.4节将介绍MATLAB引擎技术实现在其他语言环境下后台调用MATLAB命令的功能,但这种调用方法要求工作环境必须安装MATLAB应用程序,否则无法启动MATLAB引擎。

作者:德特数据
联系方式:156204968@qq.com

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,233评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,013评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,030评论 0 241
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,827评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,221评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,542评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,814评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,513评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,225评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,497评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,998评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,342评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,986评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,812评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,560评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,461评论 2 266

推荐阅读更多精彩内容