Python gzip拒绝读取未压缩的文件

mok*_*ok0 8 python gzip

我似乎记得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
Run Code Online (Sandbox Code Playgroud)

如果有人有一个巧妙的技巧,我想听听它.是的,我知道如何捕获异常,但我发现首先读取一行是相当笨拙的,然后关闭文件并再次打开它.

syn*_*tel 11

对此最好的解决方案是使用类似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'
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)


小智 5

也许你正在考虑zless或zgrep,它会打开压缩或未压缩的文件而不会抱怨.

你能相信文件名以.gz结尾吗?

if file_name.endswith('.gz'):
    opener = gzip.open
else:
    opener = open

with opener(file_name, 'r') as f:
    ...
Run Code Online (Sandbox Code Playgroud)