簡體   English   中英

Python gzip 拒絕讀取未壓縮的文件

[英]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 文件。

您可以使用fileinput(files, openhook=fileinput.hook_compressed)透明地迭代文件

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM