2012-07-18 67 views
0

我正在为学习目的而编写一个解压缩GZIP文件的C程序。如何分隔GZIP文件中的块?

按照GZIP spec

甲gzip文件由一系列 “成员”(压缩数据集)中的。 每个成员的格式在以下部分中指定。 成员只是在文件中一个接一个地出现,没有 之前,之间或之后的附加信息。

和一个构件(也许具有取决于一些标志值可选字段),某些压缩块(使用DEFLATE算法)和最后的CRC32和原始未压缩文件的大小由一个首部。

我有两个问题:

  1. 如何界定成员?实际上,一个gzip文件中是否真的有多个成员?看起来,一个成员对应一个文件(例如文件名头)
  2. 如何从尾部分隔最后一个块(CRC + SIZE)?

回答

4

这并不常见,但您有时会在单个文件中看到串联的gzip流。 gzip认为这是一个单一的数据流,而不是多个“文件”,因此文件名被忽略。

如果通过“如何定义最后一个块”来表示最后一个放气块,那么最后一个放气块在它的头部中只是有一点将其标记为最后一个块。最后的deflate块之后是crc和未压缩的长度(模2^32)。

+0

感谢您的回答,并且因为我在“specs”中的某个地方读到了您的名字;-)我在这里问另外一个问题:我没有调查过很多紧缩流压缩,但是如何分隔这些块?我只是把每个块看作是一个头,就像你说的最后一个块一样,但是我看不到“大小”信息。我如何知道什么时候正在阅读新的标题? – 2012-07-18 15:56:54

+0

放气块没有大小前缀。相反,它们是以一个结束代码自我终止的。当你到达结束码时,你会寻找一个新的块。或者,如果最后一个块位被设置在该块的开头,则处理一个预告片。 – 2012-07-18 16:59:05

+0

再次感谢。你能确认这个结束代码值是256吗? – 2012-07-19 09:17:57

1

如何分隔成员?

成员不分隔。它们之间没有分离,这就是为什么你可以将gzip文件压缩到一起,就像你不使用gzip文件一样。但是,一旦到达一个成员的末尾,就可以查找指示下一个成员开始的ID1 & ID2值。从规格:

这些具有固定值ID1 = 31(0x1f,\ 037),ID2 = 139(0x8b,\ 213),以标识文件为gzip格式。

这可以让你告诉除了文件末尾的垃圾之外的另一个成员的开始。

如果您希望跳到文件中的特定成员而不读取其他所有成员,可以使用预先计算的索引,如CDX file provides

实际上,一个gzip文件中是否真的存在多个成员?

这是很常见的gzipped WARC files(用于存档网站)。每条记录都是一个单独的成员,以方便寻求。但是,格式不依赖于此功能。