PKZIP 文件是高度结构化的,仅附加到末尾就会搞砸。我不能说早期版本的工作,但解决这个问题的方法是打开一个 zipfile 进行读取,打开一个新的文件进行写入,提取第一个的内容,然后在最后添加您的附加组件。完成后,用新创建的压缩文件替换原始压缩文件。
我在运行你的代码时得到的回溯是:
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.
经过仔细检查,我注意到您正在从以“a”挂起模式打开的类似文件的 StringIO 中读取,这应该会导致读取错误,因为“a”通常不可读,当然必须是 seek()ed在读取和写入之间。我会玩弄一些并更新它。
更新:
从 Doug Hellmann 的优秀 Python Module of the Week 中窃取了几乎所有这些代码,我发现它的工作原理与我预期的一样。不能仅仅附加到结构化的 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
它没有附加到现有的 arcname 'hosts',它创建了一个额外的存档成员。
"Je n'ai fait celle-ci plus longue que
Parce que je n'ai pas eu le loisir de
放任自流。”
- 布莱斯帕斯卡