是否可以检查文件 (.gz) 是否被多次压缩?

Is it possible to check whether a file (.gz) has been compressed more than once?

我遇到过这样一种情况:一个专有格式的文件被压缩为 .gz,随后将其重命名回其原始扩展名,然后再次压缩。我想捕捉这样的场景,想知道是否有一种方法可以检测文件何时被压缩两次。

我正在阅读 .gz 文件如下:

 GZIPInputStream gzip = new GZIPInputStream(Files.newInputStream(inFile));
 BufferedReader breader = new BufferedReader(new InputStreamReader(gzip)); 

一种蛮力方式是:解压缩文件;如果可行;尝试再次解压。如果再次有效,您就知道它被压缩了(至少两次)。但最坏的情况下,它仍然可以被压缩。

实际上;我没有其他方法可以解决这个问题。

你看,归根结底,压缩就是改变文件的字节数。所以,即使第二次压缩对文件内容没有太大影响;它仍然改变了一些字节。因此,仅通过查看这些字节,您将看不到发生了什么。

您可以检查文件中的有效 gzip header。 gzip 文件应包含定义的 header,以 2 字节数字开头,值为 0x1f 和 0x8b(请参阅 spec)。您可以检查这些字节以查看它们是否与 header 值匹配:

InputStream is = new FileInputStream(new File(filePath));
byte[] b = new byte[2];
int n = is.read(b);
if ( n != 2 ){
    //not a gzip file
}
if ( (b[0] == (byte) 0x1f) && (b[1] == (byte)0x8b)){
    //2-byte gzip header
}

仅这两个字节就有大约 1/65k 的几率随机出现,但取决于您希望收到的数据足以作为您的决定的基础。为了对调用更有信心,您可以进一步阅读 header 以确保它遵循有效的规范值(请参阅上面的 link - 例如,第三个字节通常但不总是 8 DEFLATE 压缩等等...)