.mat文件的“函数工作区”字段中包含什么?

时间:2018-09-18 19:19:09

标签: matlab scipy mat-file

我正在使用.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__字段进行反向工程。感谢Matt Bauman的这篇很有启发性的文章,也感谢@mpaskov的指针。看来__function_workspace__是各种事物的未记录的全部,实际上只有一部分是“函数工作区”。

1 个答案:

答案 0 :(得分:1)

1)区分.mat文件

您可能想看看DiffPlug。它可以处理MAT文件,我相信它也有一个命令行界面。

2)function_workspace的内容

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

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

(1)变量本身。它看起来有点像UInt32矩阵,但实际上是子系统中某个位置的Opaque对象的MCOS Reference string(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)

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

马特·鲍曼(Matt Bauman)已经做了一些出色的逆向工程工作(Parsing MAT files with class objects in them),我相信所有支持的实现都基于此。 MFL Java库包含此功能的完整(只读)实现(请参见McosFileWrapper.java)。

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

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

编辑:仅供参考,一旦正确解析了string对象并填充了所有属性,实际的字符串值就会以另一种未记录的格式编码(请参见testDoubleQuoteString