2010-09-13 57 views
20

我有一個Python程序,它將把文本文件作爲輸入。但是,其中一些文件可能被gzip壓縮。如何判斷文件是否被gzip壓縮?

是否有跨平臺,可用Python方式來確定文件是否是gzip壓縮?

以下可靠或可能是一個普通的文本文件'意外'看起來gzip就足以讓我得到誤報?

try: 
    gzip.GzipFile(filename, 'r') 
    # compressed 
    # ... 
except: 
    # not compressed 
    # ... 
+1

只是一個小提示......永遠不要依靠文件結尾。請參閱跳躍的答案如何做到這一點。 – helpermethod 2010-09-13 18:44:21

+0

@Helper:我不確定(看我的編輯)。你仍然必須處理一個可能的IOError,但沒有後綴的gzip文件被破壞,在我看來......艱難的呼叫:) – hop 2010-09-13 18:51:13

回答

34

magic number gzip的壓縮文件是1f 8b。儘管對此進行測試並非100%可靠,但「普通文本文件」以這兩個字節開始的可能性極小 - 但在UTF-8中,這甚至不合法。

雖然gzip壓縮文件通常使用後綴.gz。即使​​本身也不會在沒有它的情況下解壓縮文件,除非您使用--force。你可以想象使用它,但你仍然需要處理一個可能的IOError(你必須在任何情況下)。

你的方法的一個問題是,如果你給它一個未壓縮的文件,gzip.GzipFile()不會拋出異常。只有後面的read()會。這意味着,你可能必須執行一些你的程序邏輯兩次。醜陋。

+0

gzip壓縮文件通常具有.gz文件擴展名(事實上,我不認爲我曾見過.gzip擴展名),但依靠文件擴展名來測試文件類型通常是不安全的。 – CanSpice 2010-09-13 18:51:05

+0

@ CanSpice:當然,錯字 – hop 2010-09-13 18:52:03

+0

是嗎? - gzip C庫將透明地讀取未壓縮的文件。雖然它會寫入未壓縮的文件,但它通過它們放置CRC代碼以允許「gzip -t」(抓到我一次) – 2010-09-13 18:53:46

0

導入mimetypes模塊。 它可以自動猜測你有什麼樣的文件,以及它是否被壓縮。

mimetypes.guess_type('blabla.txt.gz') 

回報:

( 'text/plain的', '的gzip')

+12

'mimetypes'只檢查文件名的結尾,它實際上並不根據文件的內容進行猜測。 – Odinulf 2013-08-20 19:44:18

0

似乎並不在python3很好地工作......

import mimetypes 
filename = "./datasets/test" 

def file_type(filename): 
    type = mimetypes.guess_type(filename) 
    return type 
print(file_type(filename)) 

返回(None,None) 但是從unix命令「File」

:〜>文件數據集/測試 數據集/測試:gzip壓縮的數據,是 「iostat_collection」,從Unix,最後修改:星期四1月29日7時09分34秒2015年

+3

mimetypes使用juts文件名來猜測類型。要從原始文件中檢測文件類型,您需要使用「魔術」模塊。 – 2016-04-19 08:30:20

2

「有一個跨平臺,從Python的方式可用來確定文件是否是gzip壓縮?「

接受的答案讓我有90%的方式來相當可靠的解決方案(測試前兩個字節是否爲1f 8b),但沒有說明如何在Python中實際執行此操作。這裏有一種可能的方式:

import binascii 

def is_gz_file(filepath): 
    with open(filepath, 'rb') as test_f: 
     return binascii.hexlify(test_f.read(2)) == b'1f8b'