Как извлечь файл из библиотеки 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