开发导入转换器
Mathematica 提供了允许用户员实现文件格式转换的功能,该功能与 Mathematica Import 和 Export 框架相集成. 用户可以实现格式转换,并且使用 Import 从任意格式导入数据.
Mathematica 也提供了显示格式转换器如何实现与注册的开源代码. 这些代码位于文件夹 $InstallationDirectory/SystemFiles/Formats/format 中,其中 format 是下列格式之一: BDF、DIF、 MTP、SMILES、SurferGrid、TGF 或 TLE. 注册代码位于文件 Import.m 或者 Export.m 中,而转换器实现位于文件 Converter.m 中.
在 Import 和底层转化函数之间的界面由
指定(在
上下文下). 大体上,当导入一个文件格式的特定元素时,
告诉 Import 和 Export框架如何调用特定函数.
本教程使用如下专有名词:
底层函数 将文件或者流视为输入,并且返回包含导入数据的规则列表. 这里有两种类型的底层函数:(1) 默认导入器,当导入未显式注册的元素时,框架对其进行调用;(2) 条件导入器,将一个在
的第二个变量中注册的特定元素导入.
后导入器 或者后导入函数,在
的第三个变量中注册,将底层函数的输出作为输入处理.
下面总结了
的一些形式. 本教程为用户提供了循序渐进的范例,详细介绍
的各种使用.
| ImportExport`RegisterImport["format",defaultFunction] |
| 当导入一个类型为 的文件时,将单个 defaultFunction 注册为由 Import 框架所用的默认导入器 |
| ImportExport`RegisterImport["format",{"elem1"⧴conditionalFunction1,"elem2"⧴conditionalFunction2,...,defaultFunction}] | 注册由 Import 框架所用的多个元素 ( , , ...) 和各自的转换器函数 ( , , ...). 另外当所要求的元素与任何已注册元素都不匹配时,也注册所用的 defaultFunction |
| ImportExport`RegisterImport["format",{conditionalFuncs,defaultFunction},{"elem3"⧴postFunction3,"elem4"⧴postFunction4,...}] | 注册额外的转换器函数,这些函数的输入是其中一个底层函数的输出 |
默认导入器
例如,假设我们有一个包含3个头行,接着是4个由数字组成的列的文件格式.
新格式的注册和实现
一个可能的设计是对
和
元素分别导入头信息和数字. 这也可以使用
实现.
在这个特殊情况下,当导入格式为
的任意元素时,我们告诉 Import 和 Export 框架来调用函数
.
默认情况下,该框架把文件名传递给底层函数,因此
将文件名和选项集作为输入. 该函数必须以
形式返回规则列表.
导入具有新格式的文件
Import 可以将
作为一个有效文件格式使用.
| Out[4]= |  |
| Out[5]= |  |
| Out[6]= |  |
条件原始导入器
当一个格式包括多个元素时,利用特定的底层函数导入特定的元素可能是有用并且有效的. 这可以通过将形如 "elem"->func 的规则列表作为
的第二个变量给出来实现. 但是,该列表必须以默认导入器名称结束,其中该导入器在导入不与列表中明确定义的元素匹配的元素时被调用.
具有条件导入器的新格式的注册与实现
本注册方法告诉 Import 和 Export 框架如何导入格式为
的文件:
(1) 当导入
元素时,使用
;
(2) 对于所有其它元素,使用
.
该底层函数具有相同的结构,采用一个文件名以及一个选项列表(可选),并且以
形式返回规则集合.
利用 MyFormat2 导入
的导入元素的输出与
的相同,但是现在对这两个不同的元素调用两个不同的函数.
| Out[10]= |  |
| Out[11]= |  |
指定子元素
默认情况下,该框架利用 Part 导入子元素.
| Out[12]= |  |
对于包含一些大型数据集的文件,直接导入特定的数据集可能是有效的. 例如,我们可以直接从格式为 "EDF" 的文件中导入一个数据集.
| Out[13]= |  |
| Out[38]= |  |
通过注册形如
的底层函数,我们可以指定子元素的导入.
底层函数的输出必须与
形式匹配.
与前面的情况相同,另一些底层函数的输出必须是形如
的规则列表.
现在,字符串子元素的导入调用适当的底层函数.
| Out[20]= |  |
| Out[21]= |  |
后导入器
可能的情况是,我们必须基于其它元素构建元素. 例如,如果要导入的数据是表示灰度图像的数字列表,那么导入
元素要求首先导入
元素. 在本章节中,我们有两个使用
和
元素的例子.
当存在一个匹配的元素名称时,后导入器将条件导入器的输出作为输入;否则,后导入器将默认导入器的输出作为输入.
与条件导入器及默认导入器不同,后导入器只简单地返回元素值.
具有后导入器的新格式的注册与实现
为了说明条件导入器和后导入器的差异,我们使用两个额外的元素:
和
来扩展
.
元素通过一个条件导入器导入. 而
元素由后导入器导入.
下面的注册方式告诉 Import 和 Export 框架如何导入格式为
的文件:
(1) 对于
或者
元素,调用相应的条件导入器;
(2) 对于
元素,首先调用默认的导入器,并且将它的输出作为
的输入;
(3) 对于所有其它元素,调用默认的导入器.
条件导入器和默认导入器与前面的导入器具有相同的结构.
注意,
导入器必须显式调用默认导入器,并且手动提取数据.
由于没有
元素被注册为条件导入器,
元素的导入器将默认导入器的输出作为输入.
利用 MyFormat3 导入
从用户角度看,利用后导入函数或底层函数实现的元素之间没有差异.

元素注册为条件导入器.
| Out[27]= |  |
元素的导入调用后导入器 
.
| Out[28]= |  |
RegisterImport 的选项
具有一些为我们提供很大灵活度的选项.
"FunctionChannels" 和 "BinaryFormat"
在上述例子中,底层函数把文件名作为一个变量接受,并且该函数打开该文件的流. 通过把
指定为
的一个选项,该框架可以直接把 InputStream 传递给底层函数.
通过设置选项 "BinaryFormat"->True,该框架把一个二进制流传递给底层导入器.
的默认值是
.
的默认值是 False.
范例
对于注册为
的格式,eFunc 的签名为
,并且该框架把一个(非二进制)流传递给 eFunc.
"AvailableElements"
默认情况下,当导入一个未明确注册为条件导入器或后导入器的元素,该框架计算默认的导入器. 如果在默认的导入器中未找到匹配的元素,该框架产生一条错误信息,并且返回 $Failed.
通过设置选项
,当我们试图导入一个不在指定列表中出现的元素时,该框架将直接返回 $Failed,并且产生一个错误信息而不调用任何底层导入器.
范例
对于注册为
的格式,当我们调用 Import[filename, {"format", "foo"}] 时,该框架将返回 $Failed,而不计算默认导入器
.
注意,指定
是错误的. 在这种情况下,Import[filename, {"format", "elem2"}] 将返回 $Failed,因为
不位于由
指定的列表中.
"DefaultElement"
设置 "DefaultElement"->elem,其中 elem 是元素名,当没有指定 Import 元素时,该框架导入 elem.
"Sources"
选项
可用来指定 .m、.mx 或者包含底层函数定义的 MathLink.exe 文件的文件路径. 该框架将自动使用适用于源文件的 Get 或者 Install.