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()写道。我将愚弄一些并更新此内容。
更新:
从 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 la faire pluscoute。”
-布莱斯·帕斯卡