Python: открыть zip-файл из двоичного файла вместо имени файла
Есть ли способ инициализировать ZipFile
объект, передавая буквальные байты zip-файла, вместо того, чтобы он прочитал имя файла? Я создаю спокойное приложение, которому не нужно прикасаться к диску; он просто открывает файл, работает с ним, переархивирует и отправляет его дальше.
3 ответа
В комментариях к другим ответам вы говорите, что хотите сделать это:
открыть двоичную строку, как если бы это был ZIP-файл. Откройте его, прочитайте / запишите файлы внутри него, а затем закройте его
Вы просто делаете то же самое, что и в других ответах, за исключением того, что вы создаете StringIO.StringIO
(или же cStringIO.StringIO
или же io.BytesIO
), который предварительно заполнен двоичной строкой, и извлеките строку в конце. StringIO
и друзья принимают необязательную начальную строку для своего конструктора, и имеют getvalue
метод для извлечения строки, когда вы закончите. Документация очень проста, и ее стоит прочитать.
Итак, придерживаясь как можно ближе к ответу Алекса:
from zipfile import ZipFile
try:
import cStringIO as StringIO
except ImportError:
import StringIO
in_memory = StringIO.StringIO(original_zip_data)
zf = ZipFile(in_memory, "a")
zf.writestr("file.txt", "some text contents")
zf.close()
new_zip_data = in_memory.getvalue()
Тем не менее, обратите внимание, что ZipFile
на самом деле не может писать в zip-архив на месте, за исключением особого случая добавления в него новых файлов. Это так же верно для zip-архивов в памяти, как и на диске. Вы часто можете избежать перезаписи файла в архиве, добавляя новый файл с тем же путем, но обычно это плохая идея (особенно если вы создаете эти вещи для отправки через Интернет).
Итак, то, что вы, вероятно, захотите сделать, точно так же, как и в случае, когда вы хотите изменить файл: создайте отдельный выходной файл, скопируйте необходимые вам данные из входного файла и напишите новые, по мере продвижения. Просто в этом случае входные и выходные файлы ZipFile
упаковка объектов StringIO
объекты.
Конечно, вместо этого используйте (c)StringIO: http://docs.python.org/2/library/stringio.html Кроме того, вы должны использовать BytesIO для Python 3. Хотя он существует для 2.6 и 2.7.
Вот пример использования (c)StringIO
:
from zipfile import ZipFile
try:
import cStringIO as StringIO
except ImportError:
import StringIO
in_memory = StringIO.StringIO()
zf = ZipFile(in_memory, "a")
zf.writestr("file.txt", "some text contents")
zf.close()
Также см: