2013-09-23 5 views
2

Есть ли способ инициализировать объект ZipFile путем передачи в буквальных байтах zip-файла вместо того, чтобы он читал имя файла? Я создаю успокаивающее приложение, которое не нужно касаться диска; он просто открывает файл, немного работает над ним, повторно застегивает его и отправляет.Python: открыть zip-файл из двоичного файла вместо имени файла

+0

Просто, чтобы быть ясным: я хотел бы иметь возможность * открыть * zip-файл из двоичной строки. Как и в, я передаю строку, содержащую двоичные данные, и получаю объект ZipFile. Код StringIO, который я видел до сих пор, касается записи ZipFile в строку, но, похоже, не позволяет избежать записи временного файла. –

ответ

4

В комментариях к другим ответам, вы говорите, что хотите сделать это:

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

Вы просто делаете то же самое, как и в других ответах, за исключением вы создаете StringIO.StringIO (или cStringIO.StringIO или io.BytesIO), которые он предварительно заполнены двоичную строку и извлечь строку в конце. StringIO и друзья берут необязательную начальную строку для своего конструктора и имеют метод getvalue для извлечения строки, когда вы закончите. The documentation очень просто и стоит прочитать.

Так, придерживаясь как можно ближе к alecxe Ответим как можно:

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-архивов в памяти, как на диске. Вы часто можете отказаться от перезаписи файла в архиве, добавив новый файл с тем же путем, но обычно это плохая идея (особенно если вы создаете эти вещи для отправки через Интернет).

Итак, что вы, вероятно, хотите сделать, это точно так же, как если вы хотите изменить файл: создайте отдельный выходной файл, скопируйте нужные вещи из входного файла и напишите новые вещи по ходу дела. Просто в этом случае входные и выходные файлы представляют собой объекты ZipFile, обертывающие объекты StringIO.

2

Несомненно, используйте (c) StringIO вместо: http://docs.python.org/2/library/stringio.html Кроме того, вы должны использовать BytesIO для Python 3. Он существует только для 2.6 и 2.7.

+0

Я думаю, вы имеете в виду 'BytesIO', но да. – Marcin

+1

@Marcin: В Python 2.x, 'StringIO.StringIO' в порядке. В 3.x, да, вы бы вместо этого использовали 'io.BytesIO'. – abarnert

+0

@abarnert Вправо. Поэтому использование 'StringIO' просто вводит проблему переносимости без каких-либо причин. – Marcin

2

Вот пример использования (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() 

Также смотрите:

+0

Не было бы BytesIO лучше? В частности, потому что код будет переносимым между 2 и 3. – Marcin

Смежные вопросы