RIFF档案I/O

RIFF档案I/O
开放分类: 程式设计
DRUM 程式也可以储存和检索储存在DRUM结构中资讯的档案。这些档案格式都是RIFF(Resource Interchange File Format:资源交换档案格式),即一般建议使用的多媒体档案型态。当然,您可以用标准档案I/O函式来读写RIFF档案,但更简便的方法是使用字首是 mmio(对「多媒体输入/输出」)的函式。

检查.WAV格式时我们发现,RIFF是标记档案格式,这意味著档案中的资料由不同长度的资料块组成。每个资料块都用一个标记来识别。一个标记就是一个4 位元组的ASCII字串。这与32位元整数的标记名称相比要容易些。标记的後面是资料块长度及其资料。因为档案中的资讯不是位于档案开头固定的偏移量而是 用标记定义,所以标记档案格式是通用的。这样,可以透过添加附加标记来增强档案格式。在读档案时,程式可以很容易地找到所需要的资料并跳过不需要的或者不 理解的标记。

Windows中的RIFF档案由独立的资料块组成。一个资料块可以分为资料块类型、资料块大小以及资料本身。资料块类型是4字元的ASCII码标记,标 记中间不能有空格,但末尾可以有。资料块大小是一个4位元组(32位元)的值,用于显示资料块的大小。资料本身必须占用偶数个位元组,必要时可以在结尾补 0。这样,资料块的每个部分都是从档案开头就字组对齐好了的。资料块大小不包括资料块类型和资料块大小所需要的8位元组,并且不反映添加的资料。

对于一些资料块类型,资料块大小与特定档案无关,是相同的。在资料块是包含资讯的固定长度的结构时,就是这种情况。其他情况下,资料块大小根据特定档案变化。

有两个特殊型态的资料块分别称为RIFF资料块和LIST资料块。其中,资料以一个4字元ASCII形式型态开始,後面是一个或多个子资料块。LIST资 料块与RIFF资料块类似,只是资料以4字元的ASCII列表型态开始。RIFF资料块用于所有的RIFF档案,而LIST资料块只在档案内部用来合并相 关子资料块。

一个RIFF档案就是一个RIFF资料块。因此,RIFF档案以字串「RIFF」和一个表示档案长度减去8位元组的32位元值开始。(实际上,如果需要补充资料则档案可能会长一个位元组。)

多媒体API包括16个字首是mmio的函式,这些函式是专门为RIFF档案设计的。DRUMFILE.C中已经用到其中几个函式来读写DRUM资料档案。

要用mmio函式打开档案,则第一步是呼叫mmioOpen。函式传回一个档案代号。mmioCreateChunk函式在档案中建立一个资料块,这使用 MMCKINFO定义的资料块名称和特徵。mmioWrite函式写入资料块。写完资料块以後,呼叫mmioAscend。传递给mmioAscend的 MMCKINFO结构必须与前面通过传递给mmioCreateChunk来建立资料块的MMCKINFO结构相同。通过从目前档案指标中减去结构的 dwDataOffset栏位来执行mmioAscend函式,此档案指标现在位于资料块的结尾,并且此值储存在资料的前面。如果资料块在长度上不是2位 元组的倍数,则mmioAscend函式也填补资料。

RIFF档案由巢状组织的资料块套叠组成。为使mmioAscend正常工作,必须维护多个MMCKINFO结构,每个结构与档案中的一个曾级相联系。 DRUM资料档案共有三级。因此,在DRUMFILE.C中的DrumFileWrite函式中,我为三个MMCKINFO结构定义了一个阵列,可以分别 标记为mmckinfo[0]、mmckinfo[1]和mmckinfo[2]。在第一次mmioCreateChunk呼叫 中,mmckinfo[0]结构与DRUM形式型态一起用于建立RIFF型态的块。其後是第二次mmioCreateChunk呼叫,它用 mmckinfo[1]与INFO列表型态一起建立LIST型态的资料块。

第三次mmioCreateChunk呼叫用mmckinfo[2]建立一个ISFT型态的资料块,此资料块用于识别建立资料档案的软体。下面的 mmioWrite呼叫用于写字串szSoftware,呼叫mmioAscent可用mmckinfo[2]来填充此资料块的资料块大小栏位。这是第一 个完整的资料块。下一个资料块也在LIST资料块内。程式继续用另一个mmioCreateChunk来呼叫建立ISCD(creation data:建立资料)资料块,并再次使用mmckinfo[2]。在mmioWrite呼叫来写入资料块以後,使用mmckinfo[2]呼叫 mmioAscend来填充资料块大小。现在写到了此资料块的结尾,也是LIST块的结尾。所以,要填充LIST资料块的资料块大小栏位,可再次呼叫 mmioAscend,这次使用mmckinfo[1],它最初用于建立LIST资料块。

要建立「fmt」和「data」资料块,mmioCreateChunk使用mmckinfo[1];mmioWrite呼叫的後面也使用 mmckinfo[1]的mmioAscend。在这一点上,除了RIFF资料块本身以外,所有的资料块大小都填好了。这需要多次使用 mmckinfo[0]来呼叫mmioAscend。虽然有多次呼叫,但只呼叫mmioClose一次。

看起来好像mmioAscend呼叫改变了目前的档案指标,而且它的确填充了资料块大小,但在函式传回时,在资料块结束(或可能因补充资料而增加1位元组)以後,档案指标恢复到以前的位置。从应用的观点来看,所有的档案写入都是按从头到尾的顺序。

mmioOpen呼叫成功後,除了磁碟空间耗尽之外,不会发生其他错误。使用变数wError从mmioCreateChunk、mmioWrite、 mmioAscend和mmioClose呼叫累计错误代码,如果磁碟空间不足则每个呼叫都会失败。如果发生了错误,则mmioOpen以 MMIO_DELETE常数为参数来删除档案,并传回错误资讯。

读RIFF档案与建立RIFF档案类似,只不过是呼叫mmioRead而不是mmioWrite,呼叫mmioDescend而不是 mmioCreateChunk。「下降」(descend)到一个资料块,是指找到资料块位置,并把档案指标移动到资料块大小之後(或者在RIFF或 LIST资料块类型的形式型态或者列表型态的後面)。从资料块「上升」指的是把档案指标移动到资料块的结尾。mmioDescend和 mmioAscend函式都不能把档案指标移到档案的前一个位置。

DRUM以前的版本在1992年的《PC Magazine》发表。那时,Windows支援两个不同等级的MIDI合成器(称为「基本的」和「扩展的」)。那个程式写的档案有格式识别字1。本章 的DRUM程式将格式识别字设定为2。不过,它可以读取并转换早期的格式。这在DrumFileRead常式中完成。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值