簡體   English   中英

如何判斷文件是否是 gzip 壓縮的?

[英]How to tell if a file is gzip compressed?

我有一個 Python 程序,它將把文本文件作為輸入。 但是,其中一些文件可能是 gzip 壓縮的。

是否有跨平台的、可從 Python 使用的方式來確定文件是否是 gzip 壓縮的?

以下是可靠的還是普通的文本文件“不小心”看起來像 gzip 一樣足以讓我得到誤報?

try:
    gzip.GzipFile(filename, 'r')
    # compressed
    # ...
except:
    # not compressed
    # ...

gzip 壓縮文件的幻數1f 8b 盡管對此進行的測試不是 100% 可靠,但“普通文本文件”極不可能以這兩個字節開頭——在 UTF-8 中它甚至是不合法的。

不過,通常 gzip 壓縮文件的后綴是.gz 甚至gzip(1)本身也不會在沒有它的情況下解壓縮文件,除非您--force它。 您可以想象使用它,但您仍然必須處理可能的 IOError (無論如何您都必須這樣做)。

您的方法的一個問題是,如果您提供一個未壓縮的文件, gzip.GzipFile()不會引發異常。 只有稍后read()才會。 這意味着,您可能必須兩次實現某些程序邏輯。 丑。

是否有跨平台的、可從 Python 使用的方式來確定文件是否是 gzip 壓縮的?

接受的答案解釋了一般如何檢測 gzip 壓縮文件:測試前兩個字節是否為1f 8b 但是它沒有展示如何在 Python 中實現它。

這是一種方法:

def is_gz_file(filepath):
    with open(filepath, 'rb') as test_f:
        return test_f.read(2) == b'\x1f\x8b'

測試 gzip 文件的幻數是唯一可靠的方法。 但是,從 python3.7 開始,不再需要自己比較字節。 gzip 模塊將為您比較字節,如果不匹配則引發異常!

從python3.7開始,這有效

import gzip
with gzip.open(input_file, 'r') as fh:
    try:
        fh.read(1)
    except OSError:
        print('input_file is not a valid gzip file by OSError')

從 python3.8 開始,這也有效:

import gzip
with gzip.open(input_file, 'r') as fh:
    try:
        fh.read(1)
    except gzip.BadGzipFile:
        print('input_file is not a valid gzip file by BadGzipFile')

gzip本身將引發OSError如果它不是一個壓縮文件。

>>> with gzip.open('README.md', 'rb') as f:
...     f.read()
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "/Users/dennis/.asdf/installs/python/3.6.6/lib/python3.6/gzip.py", line 276, in read
    return self._buffer.read(size)
  File "/Users/dennis/.asdf/installs/python/3.6.6/lib/python3.6/gzip.py", line 463, in read
    if not self._read_gzip_header():
  File "/Users/dennis/.asdf/installs/python/3.6.6/lib/python3.6/gzip.py", line 411, in _read_gzip_header
    raise OSError('Not a gzipped file (%r)' % magic)
OSError: Not a gzipped file (b'# ')

可以將此方法與其他一些方法結合使用以增加信心,例如檢查 mimetype 或在文件頭中查找幻數(請參閱其他答案的示例)並檢查擴展名。

import pathlib

if '.gz' in pathlib.Path(filepath).suffixes:
   # some more inexpensive checks until confident we can attempt to decompress
   # ...
   try ...
     ...
   except OSError as e:
     ...

導入mimetypes模塊。 它可以自動猜測您擁有什么樣的文件,以及它是否被壓縮。

mimetypes.guess_type('blabla.txt.gz')

返回:

('文本/純文本', 'gzip')

在python3中似乎不太好用...

import mimetypes
filename = "./datasets/test"

def file_type(filename):
    type = mimetypes.guess_type(filename)
    return type
print(file_type(filename))

返回 (None, None) 但是來自 unix 命令“文件”

:~> 文件數據集/測試數據集/測試:gzip 壓縮數據,是“iostat_collection”,來自 Unix,最后修改時間:2015 年 1 月 29 日星期四 07:09:34

暫無
暫無

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

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