22.5. "chunk" --- 读取 IFF 分块数据
***********************************

**源代码:** Lib/chunk.py

======================================================================

本模块提供了一个读取使用 EA IFF 85 分块的数据的接口chunks. [1]  这种格
式使用的场合有 Audio Interchange File Format (AIFF/AIFF-C) 和 Real
Media File Format (RMFF) 等。 与它们密切相关的 WAVE 音频文件也可使用此
模块来读取。

一个chunk具有以下结构:

+-----------+----------+---------------------------------+
| 偏移      | 长度     | 目录                            |
|===========|==========|=================================|
| 0         | 4        | 区块ID                          |
+-----------+----------+---------------------------------+
| 4         | 4        | 大端字节顺序的块大小，不包括头  |
+-----------+----------+---------------------------------+
| 8         | *n*      | 数据字节，其中 *n* 是前一字段中 |
|           |          | 给出的大小                      |
+-----------+----------+---------------------------------+
| 8 + *n*   | 0 或 1   | 如果 *n* 为奇数且使用块对齐，则 |
|           |          | 需要填充字节                    |
+-----------+----------+---------------------------------+

ID是一个4字节的字符串，用于标识块的类型。

大小字段（32 位的值，使用大端字节序编码）给出分块数据的大小，不包括 8
字节的标头。

使用由一个或更多分块组成的 IFF 类型文件。 此处定义的 "Chunk" 类的建议
使用方式是在每个分块开始时实例化一个实例并从实例读取直到其末尾，在那之
后可以再实例化新的实例。 到达文件末尾时，创建新实例将会失败并引发
"EOFError" 异常。

class chunk.Chunk(file, align=True, bigendian=True, inclheader=False)

   代表一个分块的类。 *file* 参数预期为一个文件类对象。 特别地也允许该
   类的实例。 唯一必需的方法是 "read()"。 如果存在 "seek()" 和
   "tell()" 方法并且没有引发异常，它们也会被使用。 如果存在这些方法并
   且引发了异常，则它们不应改变目标对象。 如果可选参数 *align* 为真值
   ，则分块应当以 2 字节边界对齐。 如果 *align* 为假值，则不使用对齐。
   此参数默认为真值。 如果可选参数 *bigendian* 为假值，分块大小应当为
   小端序。 这对于 WAVE 音频文件是必须的。 此参数默认为真值。 如果可选
   参数 *inclheader* 为真值，则分块标头中给出的大小将包括标头的大小。
   此参数默认为假值。

   "Chunk" 对象支持下列方法：

   getname()

      返回分块的名称（ID）。 这是分块的头 4 个字节。

   getsize()

      返回分块的大小。

   close()

      关闭并跳转到分块的末尾。 这不会关闭下层的文件。

   在 "close()" 方法已被调用后其余方法将会引发 "OSError"。 在 Python
   3.3 之前，它们曾会引发 "IOError"，现在这是 "OSError" 的一个别名。

   isatty()

      返回 "False"。

   seek(pos, whence=0)

      设置分块的当前位置。 *whence* 参数为可选项并且默认为 "0" (绝对文
      件定位)；其他值还有 "1" (相对当前位置查找) 和 "2" (相对文件末尾
      查找)。 没有返回值。 如果下层文件不支持查找，则只允许向前查找。

   tell()

      将当前位置返回到分块。

   read(size=-1)

      从分块读取至多 *size* 个字节（如果在获得 *size* 个字节之前已到达
      分块末尾则读取的字节会少于此数量）。 如果 *size* 参数为负值或被
      省略，则读取所有字节直到分块末尾。 当立即遇到分块末尾则返回空字
      节串对象。

   skip()

      跳到分块末尾。此后对分块再次调用 "read()" 将返回 "b''"。 如果你
      对分块的内容不感兴趣，则应当调用此方法以使文件指向下一分块的开头
      。

-[ 备注 ]-

[1] "EA IFF 85" 交换格式文件标准, Jerry Morrison, Electronic Arts,
    1985 年 1 月。
