Проверка zip-файла, поступающего с stdin - PullRequest
1 голос
/ 11 июля 2011

После некоторого разочарования в связи с unzip(1L) я пытался создать сценарий, который будет распаковывать и распечатывать необработанные данные из всех файлов в zip-архиве, поступающем из stdin.В настоящее время у меня есть следующее, которое работает:

import sys, zipfile, StringIO

stdin = StringIO.StringIO(sys.stdin.read())
zipselect = zipfile.ZipFile(stdin)

filelist = zipselect.namelist()
for filename in filelist:
    print filename, ':' 
    print zipselect.read(filename)

Когда я пытаюсь добавить проверку, чтобы проверить, является ли это действительно файл почтового индекса, однако, это не нравится.

...

zipcheck = zipfile.is_zipfile(zipselect)
if zipcheck is not None:
    print 'Input is not a zip file.'
    sys.exit(1)

...

приводит к

File "/home/chris/simple/zipcat/zipcat.py", line 13, in <module>
  zipcheck = zipfile.is_zipfile(zipselect)
File "/usr/lib/python2.7/zipfile.py", line 149, in is_zipfile
  result = _check_zipfile(fp=filename)
File "/usr/lib/python2.7/zipfile.py", line 135, in _check_zipfile
  if _EndRecData(fp):
File "/usr/lib/python2.7/zipfile.py", line 203, in _EndRecData
  fpin.seek(0, 2)
AttributeError: ZipFile instance has no attribute 'seek'

Я предполагаю, что он не может искать, потому что это не файл, как таковой?

Извините, если это очевидно, это мой первый шаг сPython.

Ответы [ 3 ]

3 голосов
/ 12 июля 2011

Вы должны передать stdin is_zipfile, а не zipselect. is_zipfile принимает путь к файлу или объекту файла, а не ZipFile.

См. документацию zipfile.is_zipfile

Вы правы, что ZipFile не может искать, потому что это не файл. Это архив, поэтому он может содержать много файлов.

1 голос
/ 12 июля 2011

Чтобы сделать это полностью в памяти, потребуется некоторая работа. Сообщение AttributeError означает, что метод is_zipfile пытается использовать метод seek указанного вами дескриптора файла. Но стандартный ввод не доступен для поиска, и поэтому у вашего файлового объекта нет метода seek.

Если вы действительно не можете временно сохранить файл на диске, тогда вы можете буферизовать весь файл в памяти (вам нужно было бы установить ограничение размера для безопасности), а затем реализовать некоторый «утиный» код, который выглядит и действует как доступный для поиска файловый объект, но на самом деле просто использует байтовую строку в памяти.

Возможно, вы могли бы обмануть и буферизовать только достаточное количество данных для is_zipfile, чтобы выполнить свою работу, но я, кажется, напомню, что оглавление для ZIP находится в конце файла. Хотя я могу ошибаться.

0 голосов
/ 25 февраля 2018

Ваш фрагмент python2 2011 года был следующим: StringIO.StringIO (sys.stdin.read ())

В 2018 году программист на python3 может сформулировать это как: io.StringIO (...).

То, что вы хотели, это следующий фрагмент python3: io.BytesIO (...).Конечно, это хорошо работает для меня при использовании модуля requests для загрузки двоичных ZIP-файлов с веб-серверов:

zf = zipfile.ZipFile(io.BytesIO(req.content))
...