我有一个IFF风格的文件(见下文),我需要用Python检查它的内容。
https://en.wikipedia.org/wiki/Interchange_File_Format
我可以使用以下代码遍历文件
from chunk import Chunk
def chunks(f):
while True:
try:
c=Chunk(f, align=False, bigendian=False)
yield c
c.skip()
except EOFError:
break
if __name__=="__main__":
for c in chunks(file("sample.iff", 'rb')):
name, sz, value = c.getname(), c.getsize(), c.read()
print (name, sz, value)
现在我需要解析不同的值。我使用Python' struct'取得了一些成功。模块,解压缩不同的字段如下
struct.unpack('<I', value)
或
struct.unpack('BBBB', value)
通过试验结构模块文档中显示的不同格式字符
https://docs.python.org/2/library/struct.html
这适用于一些较简单的字段,但不适用于较复杂的字段。这都是反复试验。我需要的是一些解包不同值的系统方法,一些了解或检查它们所代表的数据类型的方法。我不是C数据类型专家。
有什么想法吗?非常感谢。
SVOXVERS BVER BPM }SPEDTGRDGVOL`NAME2017-02-15 16-38MSCLMZOOMXOFMYOFLMSKCURLTIMESELSLGENPATNPATTPATLPDTAa � 1pQ 10 `q !@QP! 0A �`A PCHNPLIN PYSZ PFLGPICO �m�!�a��Q�1:\<<<<:\�1�Q��a�!�mPFGCPBGC���PFFFPXXXPYYYPENDSFFFCSNAM OutputSFINSRELSXXXDSYYYhSZZZSSCLSVPRSCOL���SMICSMIB����SMIP����SLNK����SENDSFFFISNAM FMSTYPFMSFINSRELSXXX�SYYY8SZZZSSCLSVPRSCOL��SMICSMIB����SMIP����SLNKCVAL�CVAL0CVAL�CVALCVALCVALCVALCVALGCVALnCVAL\CVALCVAL&CVALoCVALDCVALCVALCVALCMID������������������SENDSFFFQSNAM EchoSTYPEchoSFINSRELSXXX�SYYY SZZZSSCLSVPRSCOL��SMICSMIB����SMIP����SLNK����CVALCVALCVAL�CVALCVALCVALCMID0������SENDSFFFQSNAM ReverbSTYPReverbSFINSRELSXXX\SYYY�SZZZSSCLSVPRSCOL��SMICSMIB����SMIP����SLNK����CVALCVALCVAL�CVAL�CVALCVALCVALCVALCVALCMIDH���������SENDSENDSENDSENDSEND
答案 0 :(得分:1)
如果它确实是一个IFF文件,则需要对齐并打开big-endian,并且该文件将包含单个FORM
块,而该块又包含FORM类型,例如SVOX
和内容大块。 (或者它可以包含一个LIST
或CAT
容器块。)
IFF块具有:
length
length
数据字节数length
为奇数时用于对齐的填充字节这在“ EA IFF 85”中有所记录。有关原始的IFF文档,请参见the "EA IFF-85" Repository。 [我写的。]
某些文件格式(例如RIFF和PNG)是IFF设计的变体,而不是IFF标准的应用程序。它们会改变块格式的详细信息,这就是Python's Chunk reader library让您选择对齐方式,字节顺序以及何时递归为块的原因。
通过在十六进制/ ascii转储中查看文件并映射出块跨度,您应该能够推断出它是使用big-endian还是little-endian length
字段,无论每个奇长块后面跟一个填充字节以进行对齐,以及块中是否有块。
现在显示内容。块的类型表示其内容的格式和语义。这些内容可以是简单的C结构,也可以包含可变长度的字符串。与JSON和TIFF不同,IFF本身不提供该结构级别的元数据。
因此请尝试查找文件格式(SVOX
?)的文档。
否则,请尝试对数据进行反向工程。如果将示例数据放入生成这些文件的应用程序中,则可以尝试特殊情况,在文件中查找期望值,仅更改一个参数,然后查找文件中更改的内容。
最后,您的代码应调用c.close()
。 c.close()
将为您呼叫c.skip()
,并处理块关闭,其中包括安全检查,以确保以后尝试读取块。