Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python gzip refuses to read uncompressed file

Tags:

python

gzip

I seem to remember that the Python gzip module previously allowed you to read non-gzipped files transparently. This was really useful, as it allowed to read an input file whether or not it was gzipped. You simply didn't have to worry about it.

Now,I get an IOError exception (in 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

If anyone has a neat trick, I'd like to hear about it. Yes, I know how to catch the exception, but I find it rather clunky to first read a line, then close the file and open it again.

like image 704
mok0 Avatar asked May 29 '13 11:05

mok0


People also ask

Is gzip a standard Python library?

This module provides us with high-level functions such as open() , compress() and decompress() , for quickly dealing with these file extensions. Essentially, this will be simply opening a file! There is no need to pip install this module since it is a part of the standard library!


2 Answers

The best solution for this would be to use something like https://github.com/ahupp/python-magic with libmagic. You simply cannot avoid at least reading a header to identify a file (unless you implicitly trust file extensions)

If you're feeling spartan the magic number for identifying gzip(1) files is the first two bytes being 0x1f 0x8b.

In [1]: f = open('foo.html.gz')
In [2]: print `f.read(2)`
'\x1f\x8b'

gzip.open is just a wrapper around GzipFile, you could have a function like this that just returns the correct type of object depending on what the source is without having to open the file twice:

#!/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
like image 151
synthesizerpatel Avatar answered Sep 20 '22 08:09

synthesizerpatel


Maybe you're thinking of zless or zgrep, which will open compressed or uncompressed files without complaining.

Can you trust that the file name ends in .gz?

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

with opener(file_name, 'r') as f:
    ...
like image 27
Rob Flickenger Avatar answered Sep 18 '22 08:09

Rob Flickenger