запись StringIO обратно на диск в python

Я создал ZIP-файл в памяти, используя StringIO и zipfile:

inMemoryZip = StringIO()
outfile = zipfile.ZipFile(inMemoryZip, 'w', compression=zipfile.ZIP_DEFLATED)
//outfile.write(stuff)
inMemoryZip.seek(0)
return inMemoryZip

Эти данные загружаются на сервер/базу данных. В какой-то момент он получен, и мне нужно записать его на диск в виде zip-файла. Я не знаю, как это сделать. Я пробовал следующее:

with open('pathToNewZip.zip', 'w') as archive:
  archive.write(inMemoryZip.getvalue())

Это создает архив zip-файла, но когда я дважды щелкаю по нему, я не вижу его содержимого, он в основном создает копию самого себя (еще один идентичный файл .zip, , но расширение .zip.cpgz ) рядом с оригиналом

Я также пробовал:

with open('pathToNewZip.zip', 'w') as archive:
      shutil.copyfileobj(inMemoryZip, archive)

но это тот же результат, что и выше.

Я предполагаю, что часть проблемы заключается в том, что я не знаю, как анализировать эти данные. inMemoryZip (экземпляр StringIO) может содержать несколько файлов.

Каждый файл записывается как новая строка?

Что возвращает .getvalue()? Данные для всех файлов в экземпляре StringIO?

Как определить имена файлов, которые я заархивировал ранее, чтобы их можно было воссоздать с тем же именем?

Вот это: Как я могу передать объект Python StringIO() в ZipFile(), или он не поддерживается? но похоже, что это работает, если за один раз записывается только 1 файл. мой экземпляр StringIO может иметь 1 файл или 10 файлов.


person duxfox--    schedule 02.03.2016    source источник
comment
Обратите внимание, что вам, вероятно, следует использовать open с wb, учитывая, что ZIP-файлы являются двоичным форматом.   -  person Alyssa Haroldsen    schedule 02.03.2016
comment
Это питон 2 или 3?   -  person tdelaney    schedule 02.03.2016


Ответы (1)


Вам нужно открыть окончательный файл «wb», как предложил @Kupiakos, иначе вы получите поврежденный архив. Другая ваша проблема заключается в том, что вам нужно закрыть zip-файл перед использованием буфера StringIO. Закрытие записывает каталог файлов в zip-файл. Без этого распаковщик может делать предположения, например, что это всего лишь один из составных zip, и делать странные вещи. Номинально просто добавьте outfile.close() или поместите его в контекстный менеджер

inMemoryZip = StringIO()
with zipfile.ZipFile(inMemoryZip, 'w', compression=zipfile.ZIP_DEFLATED) as output:
    //outfile.write(stuff)
inMemoryZip.seek(0)
return inMemoryZip

тогда позже

with open('pathToNewZip.zip', 'wb') as archive:
  archive.write(inMemoryZip.getvalue())
person tdelaney    schedule 02.03.2016
comment
Ты мужчина! Я не закрывал zip-файл, поэтому он не работал. большое спасибо - person duxfox--; 03.03.2016