Как проверить, зашифрован ли zip-файл с помощью zip-файла стандартной библиотеки python?

Я использую стандартную библиотеку Python, zipfile, для тестирования архива:

zf = zipfile.ZipFile(archive_name)
if zf.testzip()==None: checksum_OK=True

И я получаю это исключение времени выполнения:

File "./packaging.py", line 36, in test_wgt
    if zf.testzip()==None: checksum_OK=True
  File "/usr/lib/python2.7/zipfile.py", line 844, in testzip
    f = self.open(zinfo.filename, "r")
  File "/usr/lib/python2.7/zipfile.py", line 915, in open
    "password required for extraction" % name
RuntimeError: File xxxxx/xxxxxxxx.xxx is encrypted, password required for extraction

Как я могу проверить перед запуском testzip(), зашифрован ли zip? Я не нашел исключения, которое упростило бы эту работу.


person Eduard Florinescu    schedule 20.08.2012    source источник


Ответы (2)


Беглый взгляд на код библиотеки zipfile.py показывает, что вы можете проверить класс ZipInfo flag_bits, чтобы узнать, зашифрован ли файл, например:

zf = zipfile.ZipFile(archive_name)
for zinfo in zf.infolist():
    is_encrypted = zinfo.flag_bits & 0x1 
    if is_encrypted:
        print '%s is encrypted!' % zinfo.filename

Проверка того, установлен ли бит 0x1, — это то, как источник zipfile.py видит, зашифрован ли файл (может быть лучше задокументировано!) Одна вещь, которую вы можете сделать, это поймать RuntimeError из testzip(), затем перебрать infolist() и посмотрите, есть ли зашифрованные файлы в zip.

Вы также можете просто сделать что-то вроде этого:

try:
    zf.testzip()
except RuntimeError as e:
    if 'encrypted' in str(e):
        print 'Golly, this zip has encrypted files! Try again with a password!'
    else:
        # RuntimeError for other reasons....
person Zachary Hamm    schedule 20.08.2012
comment
** except **, а не catch. (+1) за изучение источника. - person mgilson; 20.08.2012
comment
Упс. Каждый раз, когда я переключаюсь с Java на Python или с Python на Java, мне приходится ловить свои уловки и исключения. Извиняюсь. - person Zachary Hamm; 20.08.2012
comment
Еще я бы посоветовал изменить # RuntimeError for other reasons ... на raise e #Unknown RuntimeError — просто чтобы продемонстрировать, что вы можете повторно вызвать перехваченное исключение. - person mgilson; 20.08.2012
comment
Это работает так, я думаю, загвоздка в том, что except RuntimeError, e: - person Eduard Florinescu; 20.08.2012

Если вы хотите поймать исключение, вы можете написать это:

zf = zipfile.ZipFile(archive_name)
try:
    if zf.testzip() == None:
        checksum_OK = True
except RuntimeError:
    pass
person Noctis Skytower    schedule 20.08.2012
comment
Да, но не может ли RuntimeError также быть вызвана ошибкой другого типа? - person Eduard Florinescu; 20.08.2012