![](/img/trans.png)
[英]Python: How to decompress a GZIP file to an uncompressed file on disk?
[英]Python gzip refuses to read uncompressed file
我似乎記得 Python gzip 模塊以前允許您透明地讀取非 gzip 文件。 這真的很有用,因為它允許讀取輸入文件,無論它是否被 gzip 壓縮。 你根本不必擔心它。
現在,我得到一個 IOError 異常(在 Python 2.7.5 中):
Traceback (most recent call last):
File "tst.py", line 14, in <module>
rec = fd.readline()
File "/sw/lib/python2.7/gzip.py", line 455, in readline
c = self.read(readsize)
File "/sw/lib/python2.7/gzip.py", line 261, in read
self._read(readsize)
File "/sw/lib/python2.7/gzip.py", line 296, in _read
self._read_gzip_header()
File "/sw/lib/python2.7/gzip.py", line 190, in _read_gzip_header
raise IOError, 'Not a gzipped file'
IOError: Not a gzipped file
如果有人有巧妙的技巧,我想聽聽。 是的,我知道如何捕捉異常,但我發現先讀取一行,然后關閉文件並再次打開它相當笨拙。
最好的解決方案是使用類似https://github.com/ahupp/python-magic和 libmagic 的東西。 您根本無法避免至少讀取標頭來識別文件(除非您隱式信任文件擴展名)
如果您感覺很簡陋,那么識別 gzip(1) 文件的神奇數字是前兩個字節是 0x1f 0x8b。
In [1]: f = open('foo.html.gz')
In [2]: print `f.read(2)`
'\x1f\x8b'
gzip.open 只是 GzipFile 的一個包裝器,你可以有一個這樣的函數,它只返回正確類型的對象,具體取決於源是什么,而不必打開文件兩次:
#!/usr/bin/python
import gzip
def opener(filename):
f = open(filename,'rb')
if (f.read(2) == '\x1f\x8b'):
f.seek(0)
return gzip.GzipFile(fileobj=f)
else:
f.seek(0)
return f
也許您正在考慮 zless 或 zgrep,它們可以毫無顧慮地打開壓縮或未壓縮的文件。
您能相信文件名以 .gz 結尾嗎?
if file_name.endswith('.gz'):
opener = gzip.open
else:
opener = open
with opener(file_name, 'r') as f:
...
讀取前四個字節。 如果前三個是 0x1f、0x8b、0x08,並且如果第四個字節的高三位為零,則從這四個字節開始啟動 gzip 壓縮。 否則寫出四個字節並繼續透明讀取。
您仍然應該有笨拙的解決方案來備份它,這樣如果 gzip 讀取仍然失敗,那么備份並透明地讀取。 但是前四個字節不太可能很好地模仿 gzip 文件,但不是 gzip 文件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.