Подтвердить что ты не робот

Как определить, сжат ли файл gzip?

У меня есть программа Python, которая будет принимать текстовые файлы в качестве входных данных. Однако некоторые из этих файлов могут быть сжаты gzip.

Существует ли кросс-платформенная, используемая с Python способ определить, сжат ли файл gzip или нет?

Является ли следующий надежный или обычный обычный текстовый файл "случайно" выглядит gzip-подобным образом, чтобы я мог получить ложные срабатывания?

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

Ответ 1

магическое число для сжатых файлов gzip 1f 8b. Хотя тестирование для этого не на 100% надежное, маловероятно, что "обычные текстовые файлы" начинаются с этих двух байтов - в UTF-8 это даже не законно.

Обычно сжатые файлы gzip имеют суффикс .gz. Даже gzip(1) сам не будет распаковывать файлы без него, если вы не --force его. Вы могли бы использовать это, но вам все равно придется иметь дело с возможным IOError (что вам нужно в любом случае).

Одна из проблем с вашим подходом заключается в том, что gzip.GzipFile() не будет генерировать исключение, если вы подадите его в несжатый файл. Только более поздний read() будет. Это означает, что вам, вероятно, придется дважды выполнить некоторую часть вашей программной логики. Некрасиво.

Ответ 2

"Существует ли кросс-платформенная, используемая с Python способ определить, сжат ли файл gzip или нет?"

Принятый ответ дал мне 90% пути к довольно надежному решению (проверьте, если первые два байта 1f 8b), но не показали, как это сделать на Python. Вот один из возможных способов:

import binascii

def is_gz_file(filepath):
    with open(filepath, 'rb') as test_f:
        return binascii.hexlify(test_f.read(2)) == b'1f8b'

Ответ 3

Импортируйте модуль mimetypes. Он может автоматически угадать, какой у вас файл, и если он сжат.

то есть.

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

возвращает:

('text/plain', 'gzip')

Ответ 4

Кажется, что не работает в python3...

import mimetypes
filename = "./datasets/test"

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

возвращает (None, None) Но из команды unix "Файл"

: ~ > файловые наборы данных/тест datasets/test: сжатые данные gzip, был "iostat_collection", из Unix, последний изменен: Thu Jan 29 07:09:34 2015