Сделайте копию zip в памяти, перебирая каждый файл ввода - PullRequest
1 голос
/ 03 февраля 2011

Python, насколько известно, не позволяет модифицировать заархивированный файл.Вот почему я хочу:

  1. Распаковать zip-файл в памяти (zip_in).
  2. Перейдите к каждому файлу в zip_in и измените его при необходимости, затем скопируйте в zip_out,На данный момент я доволен только созданием копии файла.
  3. Сохранить zip_out.

Я экспериментировал с zipfile и io, но не повезло.Частично потому, что я не уверен, как все это работает и какой объект требует какого вывода.

Рабочий код

import os
import io
import codecs
import zipfile

# Make in-memory copy of a zip file
# by iterating over each file in zip_in
# archive.
#
# Check if a file is text, and in that case
# open it with codecs.

zip_in = zipfile.ZipFile(f, mode='a')
zip_out = zipfile.ZipFile(fn, mode='w')
for i in zip_in.filelist:
    if os.path.splitext(i.filename)[1] in ('.xml', '.txt'):
        c = zip_in.open(i.filename)
        c = codecs.EncodedFile(c, 'utf-8', 'utf-8').read()
        c = c.decode('utf-8')
    else:
        c = zip_in.read(i.filename)
    zip_out.writestr(i.filename, c)
zip_out.close()

Старый пример, с проблемой

# Make in-memory copy of a zip file
# by iterating over each file in zip_in
# archive.
#
# This code below does not work properly.

zip_in = zipfile.ZipFile(f, mode='a')
zip_out = zipfile.ZipFile(fn, mode='w')
for i in zip_in.filelist:
    bc = io.StringIO() # what about binary files?
    zip_in.extract(i.filename, bc)
    zip_out.writestr(i.filename, bc.read())
zip_out.close()

Ошибка TypeError: '_io.StringIO' object is not subscriptable

1 Ответ

2 голосов
/ 03 февраля 2011

ZipFile.extract() ожидает имя файла, а не файлоподобный объект для записи. Вместо этого используйте ZipFile.read(name), чтобы получить содержимое файла. Он возвращает байтовую строку, поэтому будет отлично работать с двоичными файлами. Текстовые файлы могут требовать декодирования в Unicode.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...