GZipStream header 在 .NET 版本中是否可靠?

Is GZipStream header reliable across .NET versions?

我来到问答环节 Is there a way to know if the byte[] has been compressed by gzipstream? 一些作者说(这是真的)GZipStream{0x1f, 0x8b, 8, 0, 0, 0, 0, 0, 4, 0} 个字符作为 header 来知道一个字节数组是否是压缩字符串。

我的问题是,GZipStream header 跨 .NET 版本是否可靠?

它应该是可靠的,因为这个 header 来自 GZip 规范,因此不是 .NET 特定的。有关这些值的解释,请参阅 here

然而,根据规范,实际上只有前两个字节始终相同。第三个字节实际上总是一样的,因为目前只有一个有效值存在。以下字节可能会更改。

对于任何 GZip 格式的流,您都得到保证:

前两个字节:1f8b

下一个字节:00 用于存储(无压缩),01 用于压缩算法,02 用于打包,03 用于 lzf 和 08放气。 .NET 到目前为止总是使用 deflate,许多情况下只期望 deflate(Web 客户端只期望基于 deflate 的 gzip 作为传输或标记为 gzip 的内容编码)所以如果没有某种形式,它不太可能改变指定正在添加的选项。

接下来是文件类型,00 表示 "probably some sort of text file" 因为 GZipStream 没有关于文件类型的信息,它总是使用那个。

后四位是Unix格式的文件修改时间。同样,由于 class 没有关于文件的信息——因为它接收的是流,而不是带有元数据的文件,所以这些总是设置为 0。

下一个字节取决于压缩方法。使用 deflate 可以是 2 表示重度压缩或 4 表示轻度压缩。

下一个(您序列中的最后一个)取决于使用的 OS 类型。 0 表示 "FAT Filesystem" 但 Windows 继续使用,因为 Windows 已转移到使用其他文件系统,如 NTFS。如果在非 Windows 文件系统上与 Mono 一起使用,它可能具有不同的值,尽管这种情况也可能决定匹配 .NET 行为。 (更新:至少某些版本的 Mono 会在非 Windows 系统上将文件系统标志设置为 0 以外的值)。

gzip 流肯定以 0x1f 0x8b 0x08 开头。除了第三个字节中的 0x08 之外,不支持其他压缩方法。

因此,如果您没有看到 0x1f 0x8b 0x08,则它不是 gzip 流。然而,如果你确实看到0x1f 0x8b 0x08,那么它可能可能不是是一个gzip溪流。可能是,但你不能假设。

您应该对候选 gzip 文件做的是直接开始解压缩它。如果没有 gzip header,解码器将立即识别,并且如果有意外的 gzip header,则会很快检测到压缩数据中的问题。您不必检查 header,因为解码器已经这样做了,并且在那之后检查有效的压缩数据。