16

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

誰かが巧妙なトリックを持っているなら、私はそれについて聞きたいです. はい、例外をキャッチする方法は知っていますが、最初に行を読み取ってからファイルを閉じてから再度開くのはかなり面倒です。

4

4 に答える 4

14

これに対する最善の解決策は、libmagic でhttps://github.com/ahupp/python-magicのようなものを使用することです。少なくともヘッダーを読み取ってファイルを識別することを避けることはできません (ファイル拡張子を暗黙的に信頼しない限り)。

質素だと感じているなら、gzip(1) ファイルを識別するためのマジック ナンバーは、最初の 2 バイトが 0x1f 0x8b であることです。

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

gzip.open は GzipFile の単なるラッパーです。ファイルを 2 回開くことなく、ソースが何であるかに応じて正しいタイプのオブジェクトを返すだけの関数を使用できます。

#!/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
于 2013-05-29T14:28:08.017 に答える
9

おそらく、圧縮ファイルまたは非圧縮ファイルを問題なく開くことができる zless または zgrep を考えているのではないでしょうか。

ファイル名が .gz で終わることを信頼できますか?

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

with opener(file_name, 'r') as f:
    ...
于 2013-09-19T23:54:25.003 に答える