Cora
Март 2, 2010 17:18:44
Модуль zipfile из стандартной библиотеки Python 3.0 не понимает русские буквы в названиях заархивированных файлов. Какую кодировку надо ставить? Я перепробовала и utf-8, и 1251, и кои8, и исо.
Я так понимаю, менять надо в этом месте:
if flags & 0x800:
# UTF-8 file names extension
filename = filename.decode('utf-8')
else:
# Historical ZIP filename encoding
filename = filename.decode('cp437')
Заранее спасибо
Андрей Светлов
Март 2, 2010 19:01:55
имена должны быть unicode - дальше zipfile сам разберется
Cora
Март 3, 2010 07:26:23
А как их сделать unicode? Если, например, zip-архив из Инета скачан?
Андрей Светлов
Март 3, 2010 14:35:47
на распаковке все просто: по стандарту имена могут быть или utf-8 или не указаны. Различаются битом в флагах, как вы видели. Питон сам понимает этот бит и пытается работать соответственно. Если кодировка не указана - лучше думать, что это ascii.
Беда в том, что некоторые относительно старые версии архиваторов (по крайней мере для винды) упаковывали файлы в mbcs. В случае русских букв это означает cp1251. zipfile, когда видит такое безобразие - сильно смущается. Красиво чинить его довольно долго, зато сделать грязный monkey patch FileInfo._decodeFilename - 5 минут.
Cora
Март 3, 2010 15:38:46
Как сделать? Я правильно понимаю, что надо в своем коде этот monkey patch прописывать? Можно пример, пожалуйста?
Например, как исправить:
def zipdir(zipname):
“”“выдает список файлов в zip-архиве”“”
arc = zipfile.ZipFile(zipname, ‘r’)
return arc.namelist()
Или хотя бы куда посмотреть за аналогичными примерами по кодировкам?
Андрей Светлов
Март 5, 2010 12:34:26
def zipdir(zipname):
"""выдает список файлов в zip-архиве"""
store = zipfile.ZipInfo._decodeFilename
def _decodeFilename(self):
return self.filename.decode('cp1251')
zipfile.ZipInfo._decodeFilename = _decodeFilename
try:
arc = zipfile.ZipFile(zipname, 'r')
return arc.namelist()
finally:
zipfile.ZipInfo._decodeFilename = store
Cora
Март 7, 2010 14:23:49
Спасибо большое, Андрей. Все равно закорючки пишет, но, по крайней мере, хоть что-то еще можно попробовать