记一次 java 读取 matlab 数据方式
背景,了解一下
目前在做一个有点科研性质的软件项目,应用程序难免要涉及到一些科学计算上相关的东西,而 matlab 是科学计算领域最常用的工具,这不,刚接到产品经理描述的需求,用户会将 matlab 产生的结果文件(.mat)上传到系统,系统解析这个结果,然后在网页上展示。虽说最近哈工大被禁用 matlab 风波一时,大家隐忧不解,但是没有好的替代品前,还是得硬着头皮继续用着(客户不是哈工大,还可以用)。 在接到这样的需求时,首先去确认了下能否实现,随手 baidu,出来不少神仙们写的 java 读取 matlab 数据的博客,内心放心了一大半,能解决就好。产品经理一听能够解决,心里美滋滋,以最快的速度进行了需求确认->产品设计->评审、并向客户要了份测试数据交了过来,于是那时那刻手里攥着一份.mat 数据,对它还一所知。
问题解决思路
接下来就得以科学严谨的态度来解决问题了,大概分这样几步:
找研究算法同事(他们的电脑一般都装有 matlab)帮忙打开这个.mat 文件,看看它长什么样子(何方妖怪),结果,清秀的像个 excel 表格。
先了解下 matlab,所谓磨刀不误砍柴工。有些道友可能会直接施展 CV 大法,轻松搞定。但是如果根基薄弱的话,还是不建议这样做,提前了解多一些,还是多少可以减少点后期的问题,而且也能更加从容的应对后续的变化。
动手、尝试与封装
matlab 扫盲学习,简单总结
Matlab 可以说是一个计算平台,也可以说是一门高级语言,它有着自定义的数据类型,和其他语言相似,也有数值、字符、map 等。下图是在后续实现中看到的封装 matlab 数据类型类的部分截图:
比较疑惑的可能是 sparse 和 cell 。sparse 是稀疏矩阵,cell 是索引数据容器的数据类型,它是一个数组,只是数组里存放的是其他类型数据的索引。数组和矩阵是 matlab 总信息和数据的基本表示形式。
通过官网学习是才是扫盲的第一步, 从matlab语言基础知识可以了解到更多数据类型的介绍,比如 table 类型,还记的.mat 打开后清秀的样子吗,大胆猜测产品经理拿来的数据可能就和 table 有关。
扫盲方式: 先从官网学习,一知半解,然后再实践中对照印证。
动手,尝试过程记录
百度一下清一色 都是使用 ujmp-jmatio 来实.mat 文件内容的读写,
1. 尝试使用 jmatio, 结果失败了。
首先在项目中引入
实在读取 mat 文件,结果报错了
ujmp-jmatio 实际上也是引用了 jmatio, 再进行了一层封装,尝试使用 ujmp-jmatio 结果抛了同样的错误,怀疑是不是版本的问题,看了 mvnrepository, 只有 1.0 版本,matlab 不同版本数据定义有差异,估计我拿到的文件版本确实不兼容了。 这条路没有再深究下去。
2. 转换为 mfl,结果成功了
在 github 搜索了一番,找到项目 https://github.com/HebiRobotics/MFL, 引入项目尝试
很庆幸,没有再报错了,看看打印出来的结果:
从结果可以看出文件有两个主体,一个是 name 为 QA_table 的 table, 另一个是 name 为空串的 unit8, 第一个应该就是要读取的主体内容(1x6600 unit8 一时没弄明白是什么含义),MFL 库中没有 table 结构相关的封装类,但是可以直接使用 getStruct 来获取。
假如要读取图 1 中 filename 列中的三行分别的值,先简单分析下 file 打印的信息(以下没有任何官方说明,仅为个人推测和实践):
ndims: 表示维度,当前为 2 维数据
nrow3: 数据行数,3 行,和图 1 是一致的。
nvars: 变量个数,等同于列数
varnames: 存放列名
data: 存放数据
props:表的属性
以下是具体读取信息的代码:
之所以像上面这般读取,是因为给的数据结构是 116 cell 数组,数组内元素 是 31 的 cell 数组;
接来下就是封装工具,将表格转为 json 数据,提供给业务方调用,具体代码就不贴了。整个过程就是如此,感谢抽空阅读。
参考文档
版权声明: 本文为 InfoQ 作者【Lazy】的原创文章。
原文链接:【http://xie.infoq.cn/article/1df7f0be11d30e6a5ce1fb828】。文章转载请联系作者。
评论