Как извлечь файл из библиотеки python zipfile при изменении его имени

Это вызвано проблемами с файлами путей (к сожалению, в моем случае это не так).

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

def unzip_file(zipfile_path):
    z = zipfile.ZipFile(zipfile_path)
    # get pathname without extension
    directory = os.path.splitext(zipfile_path)[0]
    print directory
    if not os.path.exists(directory):
        os.makedirs(directory)
    #this line doesn't work. tries to extract "Foobar\\baz.quux" to directory and complains that the directory doesn't exist
    # z.extractall(directory)
    for name in z.namelist():
        # actual dirname we want is this
        # (dirname, filename) = os.path.split(name)
        # I've tried to be cross-platform, (see above) but aparently zipfiles save filenames as
        # Foobar\filename.log so I need this for cygwin
        dir_and_filename = name.split('\\')
        if len(dir_and_filename) >1:
            dirname = dir_and_filename[0:-1]
            filename = dir_and_filename[-1]
        else:
            dirname = ['']
            filename = dir_and_filename[0]

        out_dir = os.path.join(directory, *dirname)
        print "Decompressing " + name + " on " + out_dir
        if not os.path.exists(out_dir):
            os.makedirs(out_dir)
        z.extract(name, out_dir)
    return directory

в то время как это кажется слишком сложным, это попытка обойти некоторые ошибки, которые я нашел. Один из членов почтового файла Foobar\\filename.log, при попытке извлечь, что он жалуется, что каталог не существует. Мне нужен способ использовать такой метод:

zipfile.extract_to(member_name, directory_name, file_name_to_write)

где имя члена - это имя члена, который нужно прочитать (в этом примере Foobar\\filename.log), directory_name - это имя каталога, в который мы хотим записать, а file_name_to_write - это имя файла, который мы хотим записать (в этом случае это будет filename.log). Кажется, это не поддерживается. У кого-нибудь есть какие-нибудь идеи о том, как получить кроссплатформенную реализацию для извлечения такого рода zip-архива, который имеет вложенные выражения?

Согласно этому ответу имеющийся у меня zipfile может не соответствовать спецификациям zipfile (в нем говорится, что:

Все косые черты ДОЛЖНЫ быть прямыми косыми чертами '/', в отличие от обратных косых черт '\' для совместимости с файловыми системами Amiga и UNIX и т. Д.

в спецификации zipfile 4.4.17) Как мне решить эту проблему?

1 ответ

Решение

Я решил это, просто обстреливая unzip, Нам нужно проверить код выхода 0 или 1, так как код выхода один возвращается unzip команда (из-за неправильно сформированного zip-файла, данное сообщение является чем-то вроде warning: zipfile appears to contain backslashes as path separators,

#!/bin/bash
unzip $1 -d $2
exit_code=$?
# we catch exit_codes < 2 as the zipfiles are malformed
if [ $exit_code -lt 2 ]
then exit 0
else exit $exit_code
fi
Другие вопросы по тегам