为什么是GZIP;os";在Java中硬编码为FAT的头文件?

为什么是GZIP;os";在Java中硬编码为FAT的头文件?,java,gzip,Java,Gzip,第2.3.1节规定GZIP头必须包含OS标志: OS(操作系统)。这标识进行压缩的文件系统的类型。这可能有助于确定文本文件的行尾约定。当前定义的值如下所示: 然而,Java的GZIP序列化在所有情况下都会写入一个零,如图所示。我已经在四种不同的操作系统上运行了测试,以确认没有其他代码在编写后修改此头 为什么该值是硬编码的?正如Elliott指出的,根据您参考的同一RFC的第2.3.1.2节,将其设置为默认值是可以的: 兼容压缩器必须生成具有正确ID1、ID2、CM、CRC32和ISIZE的文件,

第2.3.1节规定GZIP头必须包含
OS
标志:

OS
(操作系统)
。这标识进行压缩的文件系统的类型。这可能有助于确定文本文件的行尾约定。当前定义的值如下所示:

然而,Java的GZIP序列化在所有情况下都会写入一个零,如图所示。我已经在四种不同的操作系统上运行了测试,以确认没有其他代码在编写后修改此头


为什么该值是硬编码的?

正如Elliott指出的,根据您参考的同一RFC的第2.3.1.2节,将其设置为默认值是可以的:

兼容压缩器必须生成具有正确ID1、ID2、CM、CRC32和ISIZE的文件,但可以将标头固定长度部分中的所有其他字段设置为默认值(操作系统为255,所有其他字段为0)。压缩机必须将所有保留位设置为零


但是,根据这个片段,默认值仍然不正确,
OS
标志的默认值是255,而不是0。根据,这是JDK中一个已知的bug。它是在Java版本16,早期access build 16中修复的。

关于某些设计最初动机的问题总是很难回答。我们可能会推测,字段值实际上在实践中并没有太大帮助,并且gzip文本文件可能是由不同于gzip的平台生成的。此外,压缩文件的应用程序g(un)并不总是读取文件的应用程序,当压缩不是API的一部分时,将标志传递给调用者。我将向您指出第2.3.1.2节,其中(部分)指出,兼容的压缩器必须生成具有正确ID1、ID2、CM、CRC32和ISIZE的文件,但可以将标题固定长度部分中的所有其他字段设置为默认值(操作系统为255,所有其他字段为0)。压缩器必须将所有保留位设置为零。@ElliottFrisch很好!但这难道不意味着代码应该将操作系统标志设置为255而不是0吗?@KonradRudolph同意这一点——在当今时代,这个字段似乎没有什么用处。我只是好奇,是否有人知道这背后的思想过程——它似乎不像Elliott指出的那样是一个必需的标志,但即使如此,它的默认值似乎也是错误的。也没有关于这方面的错误报告,所以我认为忽略这些标题是一种被广泛接受的行为。我也是这么看的,我猜他们选择
0
是出于兼容性的原因。显然
0
有效。但我认为你发现了一个bug。做得好。我认为值得注意的是,不需要兼容的压缩器来生成正确的操作系统字段。操作系统的
255
值出现在一个以“但可能”开头的句子中,因此当前的实现仍然是兼容的。
  0 - FAT filesystem (MS-DOS, OS/2, NT/Win32)
  1 - Amiga
  2 - VMS (or OpenVMS)
  3 - Unix
  4 - VM/CMS
  5 - Atari TOS
  6 - HPFS filesystem (OS/2, NT)
  7 - Macintosh
  8 - Z-System
  9 - CP/M
 10 - TOPS-20
 11 - NTFS filesystem (NT)
 12 - QDOS
 13 - Acorn RISCOS
255 - unknown