Файл PKZIP очень структурирован, и простое добавление в конец облажает его. Я не могу говорить о работе более ранних версий, но решение этой проблемы - открыть zip-файл для чтения, открыть новый для записи, извлечь содержимое первой и затем добавить свои дополнительные компоненты в конце. По завершении замените исходный zip-файл на только что созданный.
Трассировка, которую я получаю, когда запускаю ваш код, когда запускаю ваш код:
Traceback (most recent call last):
File "zip.py", line 19, in <module>
Foo()
File "zip.py", line 17, in Foo
print zip.read("bar")
File "/usr/lib/python2.6/zipfile.py", line 834, in read
return self.open(name, "r", pwd).read()
File "/usr/lib/python2.6/zipfile.py", line 874, in open
zinfo.orig_filename, fname)
zipfile.BadZipfile: File name in directory "bar" and header "foo" differ.
При ближайшем рассмотрении я замечаю, что вы читаете из файла-подобного StringIO, открытого в режиме 'a'ppend, что должно приводить к ошибке чтения, так как' a 'обычно не читается и, безусловно, должен искать () ed между чтением и записью. Я собираюсь дурачиться и обновлять это.
Обновление:
Украдя почти весь этот код из превосходного Python-модуля недели Дуга Хеллмана , я обнаружил, что он работает почти так, как я ожидал. Нельзя просто добавить к структурированному файлу PKZIP, и если код в оригинальном посте когда-либо работал, это было случайно:
import zipfile
import datetime
def create(archive_name):
print 'creating archive'
zf = zipfile.ZipFile(archive_name, mode='w')
try:
zf.write('/etc/services', arcname='services')
finally:
zf.close()
def print_info(archive_name):
zf = zipfile.ZipFile(archive_name)
for info in zf.infolist():
print info.filename
print '\tComment:\t', info.comment
print '\tModified:\t', datetime.datetime(*info.date_time)
print '\tSystem:\t\t', info.create_system, '(0 = Windows, 3 = Unix)'
print '\tZIP version:\t', info.create_version
print '\tCompressed:\t', info.compress_size, 'bytes'
print '\tUncompressed:\t', info.file_size, 'bytes'
print
zf.close()
def append(archive_name):
print 'appending archive'
zf = zipfile.ZipFile(archive_name, mode='a')
try:
zf.write('/etc/hosts', arcname='hosts')
finally:
zf.close()
def expand_hosts(archive_name):
print 'expanding hosts'
zf = zipfile.ZipFile(archive_name, mode='r')
try:
host_contents = zf.read('hosts')
finally:
zf.close
zf = zipfile.ZipFile(archive_name, mode='a')
try:
zf.writestr('hosts', host_contents + '\n# hi mom!')
finally:
zf.close()
def main():
archive = 'zipfile.zip'
create(archive)
print_info(archive)
append(archive)
print_info(archive)
expand_hosts(archive)
print_info(archive)
if __name__ == '__main__': main()
Известен вывод из последнего вызова print_info
:
...
hosts
Modified: 2010-05-20 03:40:24
Compressed: 404 bytes
Uncompressed: 404 bytes
hosts
Modified: 2010-05-27 11:46:28
Compressed: 414 bytes
Uncompressed: 414 bytes
Он не добавлялся к существующему имени дуги 'hosts', он создал дополнительного члена архива.
"Je n'ai fait celle-ci plus longue que
Parce Que Je N'ai Pas EU Le Loisir де
la faire plus courte. "
- Блез Паскаль