Не удается распаковать архив, созданный с помощью zipfile (Python) - PullRequest
4 голосов
/ 19 мая 2011

У меня проблемы с архивом, который я создал с помощью zipfile в Python. Я перебираю все файлы в каталоге и записываю их в архив. Когда я пытаюсь извлечь их позже, я получаю исключение, связанное с разделителем пути.

the_path= "C:\\path\\to\\folder"
zipped= cStringIO.StringIO()
zf = zipfile.ZipFile(zipped_cache, "w", zipfile.ZIP_DEFLATED)
for dirname, subdirs, files in os.walk(the_path) :
    for filename in files:
        zf.write(os.path.join(dirname, filename), os.path.join(dirname[1+len(the_path):], filename))
zf.extractall("C:\\destination\\path")
zf.close()
zipped_cache.close()

Вот исключение:

zipfile.BadZipfile: имя файла в каталог "env \ index" и заголовок «env / index» отличается.

Обновление: я заменил строковый буфер cStringIO.StringIO() временным файлом (tempfile.mkstemp("temp.zip")), и теперь он работает. Что-то происходит, когда модуль zipfile записывает в буфер, который повреждает архив, хотя не уверен, в чем проблема.

Проблема заключалась в том, что я считывал / записывал информацию из / в файлы, которые были открыты в режиме «r» / «w» вместо «rb» / «wb». Это не проблема в Linux, но она дала мне ошибки в Windows из-за кодировки символов. Решаемые.

Ответы [ 4 ]

5 голосов
/ 19 мая 2011

Вам следует рассмотреть возможность добавления r перед строкой, чтобы указать, что это необработанная строка - обратные слеши в пути интерпретируются как escape-символы.

Следующий код:

#!/bin/env python    
print(r"C:\destination\path")
print(r"C:\path\to\folder")
print("C:\destination\path")
print("C:\path\to\folder")

производит следующий вывод:

C:\destination\path
C:\path\to\folder
C:\destination\path
C:\path o
         older

Обратите внимание, что \ t и \ f интерпретируются как tab и formfeed впоследняя строка.

Интересно, что вы также можете изменить обратную косую черту на прямую косую черту (например, open("C:/path/to/folder"), что сработает.

Или избежать обратной косой черты с помощью ... обратной косой черты (т.е. open("C:\\path\\to\\folder")).

ИМО, самое ясное и простое решение - просто добавить r .


Редактировать: похоже, вам нужно идти сВторое решение, косые черты.Библиотека zipfile, по-видимому, довольно строгая, и, учитывая, что это ошибка только для окна, она, вероятно, пробралась.(См. Выпуск 6839 ).

3 голосов
/ 21 мая 2011

Нашел ответ на мой вопрос здесь: http://www.penzilla.net/tutorials/python/scripting.

Я вставляю две функции, которые относятся к архивированию каталога. Проблема была не в строковом буфере и не в косых чертах, а в том, как я перебирал и записывал в zip-файл. Эти 2 рекурсивные функции решают проблему. Итерирование по всему дереву подкаталогов с os.walk не является хорошим способом написать архив.

def zippy(path, archive):
    paths = os.listdir(path)
    for p in paths:
        p = os.path.join(path, p) # Make the path relative
        if os.path.isdir(p): # Recursive case
            zippy(p, archive)
        else:
            archive.write(p) # Write the file to the zipfile
    return

def zipit(path, archname):
    # Create a ZipFile Object primed to write
    archive = ZipFile(archname, "w", ZIP_DEFLATED) # "a" to append, "r" to read
    # Recurse or not, depending on what path is
    if os.path.isdir(path):
        zippy(path, archive)
    else:
        archive.write(path)
    archive.close()
    return "Compression of \""+path+"\" was successful!"
1 голос
/ 20 мая 2011

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

1 голос
/ 19 мая 2011

Вам необходимо избежать обратной косой черты в ваших путях.

Попробуйте изменить следующее:

  • the_path= "C:\path\to\folder" на the_path = "C:\\path\\to\\folder" и
  • zf.extractall("C:\destination\path") до zf.extractall("C:\\destination\\path").
...