2011-05-19 217 views
21

我有一個C/C++程序,它需要讀取一個文件,該文件可能是gzip壓縮文件,也可能不是gzip壓縮文件。我知道我們可以使用zlib中的gzread()讀取壓縮文件和未壓縮文件 - 但是,如果文件是gzip壓縮(出於性能原因),我只想使用zlib函數。如何檢查文件是否被gzip壓縮?

那麼有沒有什麼辦法可以通過程序檢測或檢查某個文件是否從C/C++中進行了壓縮?

+1

@Rob Kennedy:對於未壓縮文件,存在巨大差異 - 1min(fread)與20mins(gzread)。可能需要使用舊版本的zlib,但現在我不能使用最新版本 - 所以必須進行條件讀取。 – 2011-05-19 13:48:35

回答

42

在文件的開頭有一個幻數。只需讀取前兩個字節並檢查它們是否等於0x1f8b

+28

請注意字節順序和字節寬度。比較單個值而不是組合:'(byte1 == 0x1f)&&(byte2 == 0x8b)'與'first2bytes == 0x1f8b'。 – pmg 2011-05-19 13:42:02

+0

@pmg:謝謝你的擡頭。 :) – 2011-05-19 13:59:02

1

您可以測試RFC 1951和1952中描述的簽名以獲取想法。對於GZIP文件,第二個是相關的,它是確定性的。對其他格式有一些誤報,所以您應該檢查儘可能多的頭部以確定合理的值。

對於zlib流,它有點難度,因爲它們更容易出現誤報。但是你很少會在野外遇到那些人。

3

使用gzread()讀取壓縮文件和未壓縮文件的性能有什麼區別?

無論如何,爲了檢測文件是否被壓縮,您可以根據鏈接在文件開頭讀取magic number,即1f 8b

+0

關於性能:有非常大的差異 - 1分鐘(fread)與20分鐘(gzread)的未壓縮文件。可能需要使用舊版本的zlib,但現在我無法使用最新版本 - 所以必須使用條件讀取來解決此問題。 – 2011-05-19 13:52:36

8

你喜歡誤報,假陰性,還是根本沒有假結果(這樣的表現是不錯的......)?

RFC 1952: GZIP file format specification version 4.3表示該文件的前兩個字節(每個成員,因此)是'\x1F''\x8B'。將其用於可能導致誤報的第一次檢查。