.mat 文件的"function workspace"字段中包含什么?



我正在处理保存在程序末尾的.mat文件。命令为save foo.mat,因此所有内容都将被保存。我希望通过检查.mat文件来确定程序是否发生了更改。我看到,从一次运行到另一次运行,.mat文件的大部分都是相同的,但标记为__function_workspace__的字段有些变化。

(我正在通过scipy.io.loadmat检查.mat文件——只是加载文件并将其打印为纯文本,然后比较文本。我发现Matlab中的save -ascii不会在东西上添加字符串标签,所以使用Python是迂回的,但我会得到标签,这很有用。)

我正试图确定这些变化源自何处。有人能解释一下__function_workspace__包含什么吗?为什么从一个给定程序的一次运行到下一次运行都不一样?

我真正感兴趣的变量是一样的,但我担心我可能忽略了一些可能会反噬我的变化。提前感谢你对这个问题的任何了解。

编辑:正如我在评论中提到的,__function_workspace__的值是一个整数数组。我查看了数组的元素,发现这些数字是ASCII或非ASCII字符代码。我看到的字符序列看起来像变量或函数的名称,所以这是有意义的。但也有一些字符(非ASCII)似乎不是名称的一部分,还有很多空(零)字符。所以,除了在__function_workspace__中看到事物的名称之外,我不确定这些东西到底是什么。

第二版:我发现在注释掉对绘图函数的调用后,__function_workspace__的内容从程序的一次运行到下一次运行都是一样的,所以这太棒了。在这一点上,从一次运行到下一次运行的唯一区别是有一个__header__字段,该字段包含创建.mat文件的时间戳,该时间戳随运行而变化。

第三版:我找到一篇文章,http://nbviewer.jupyter.org/gist/mbauman/9121961"分析含有类对象的MAT文件",关于__function_workspace__字段的逆向工程。感谢马特·鲍曼的这篇极具启发性的文章,也感谢@mpaskov的指点。__function_workspace__似乎是各种东西的一个未记录的catch-all,其中只有一部分实际上是"函数工作区"。

1)区分.mat文件

您可能需要查看DiffPlug。它可以处理不同的MAT文件,我相信它也有一个命令行接口。

2) 功能内容_工作空间

SciPy的__function_workspace__是指MAT文件末尾的一个特殊变量,该变量包含引用类型(例如tablestringhandle等)所需的额外数据以及官方文档中未涵盖的各种其他内容。该名称具有误导性,因为它实际上指的是"子系统"(在官方规范中作为标题中的偏移量简要提及)。

例如,如果保存引用类型,例如emptyString = "",则生成的.mat将包含以下两个条目:

(1) 变量本身。它看起来有点像UInt32矩阵,但实际上是子系统中某个位置的string对象的OpaqueMCOS Reference(MATLAB类对象系统)。

[0] Compressed (81 bytes, position = 128)
[0] Matrix (144 bytes, position = 0)
[0] UInt32[2] = [17, 0] // Opaque
[1] Int8[11] = ['emptyString'] // Variable Name
[2] Int8[4] = ['MCOS'] // Object Type
[3] Int8[6] = ['string'] // Class Name
[4] Matrix (72 bytes, position = 72)
[0] UInt32[2] = [13, 0] // UInt32
[1] Int32[2] = [6, 1] // Dimensions
[2] Int8[0] = [''] // Variable Name (not needed)
[3] UInt32[6] = [-587202560, 2, 1, 1, 1, 1] // Data (Reference Target)

(2) 文件末尾的一个没有名称的UInt8矩阵(SciPy将其重命名为__function_workspace__)。除了缺少名称之外,它看起来像一个标准矩阵,但数据实际上是另一个包含真实数据的MAT文件(具有缩减的标头)。

[1] Compressed (251 bytes, position = 217)
[0] Matrix (968 bytes, position = 0)
[0] UInt32[2] = [9, 0] // UInt8
[1] Int32[2] = [1, 920] // Dimensions
[2] Int8[0] = [''] // Variable Name
[3] ... 920 bytes ... // Data (Nested MAT File)

不幸的是,数据的格式完全没有记录,而且有些混乱。我可以发布子系统的内容,但即使对于这样一个简单的案例,它也会变得有些不堪重负。它本质上是一个MAT文件,包含一个struct,其中包含一个特殊变量(MCOS FileWrapper__),该变量包含一个具有各种值的单元数组,其中包括一个神奇地编码各种Object Properties的数组。

Matt Bauman做了一些伟大的逆向工程工作(解析MAT文件和其中的类对象),我相信所有支持的实现都是基于这些工作。MFL Java库包含了这方面的完整(只读)实现(请参阅McosFileWrapper.Java)。

我们发现Matt Bauman帖子的一些更新是:

  • MCOS引用可以引用句柄对象的数组,并且可能具有6个以上的值。它包含大小信息,后面跟着一组索引(请参阅McosReference.java)
  • Object Id字段看起来像是一个唯一的id,但顺序似乎是随机的,有时不匹配。我不知道这个值是什么,但完全忽略它似乎效果很好:)
  • 我看到Segment 5填充在.fig文件中,但我还无法缩小其中的内容

Edit:Fyi,一旦string对象被正确解析并填写了所有属性,实际字符串值就会以另一种未记录的格式编码(请参阅testDoubleQuoteString)

最新更新