gpt4 book ai didi

Python 2.6 不喜欢附加到 zip 文件中的现有文件

转载 作者:太空狗 更新时间:2023-10-30 01:30:34 26 4
gpt4 key购买 nike

在我正在处理的程序的一些 Python 单元测试中,我们使用内存中的 zip 文件进行端到端测试。在 SetUp() 中,我们创建了一个简单的 zip 文件,但在某些测试中,我们想要覆盖一些存档。为此,我们执行“zip.writestr(archive_name, zip.read(archive_name) + new_content)”。有点像

import zipfile
from StringIO import StringIO

def Foo():
zfile = StringIO()
zip = zipfile.ZipFile(zfile, 'a')
zip.writestr(
"foo",
"foo content")
zip.writestr(
"bar",
"bar content")
zip.writestr(
"foo",
zip.read("foo") +
"some more foo content")
print zip.read("bar")

Foo()

问题是这在 Python 2.4 和 2.5 中工作正常,但 2.6。在 Python 2.6 中,这在打印行上失败,显示“BadZipfile:目录“bar”和标题“foo”中的文件名不同。”

它似乎正在读取正确的文件 bar,但它认为它应该读取 foo。

我很迷茫。我究竟做错了什么?这不支持吗?我尝试在网上搜索但找不到类似问题的提及。我阅读了 zipfile 文档,但找不到任何(我认为是)相关的内容,特别是因为我正在使用文件名字符串调用 read()。

有什么想法吗?

提前致谢!

最佳答案

PKZIP 文件是高度结构化的,仅仅附加到末尾就会搞砸。我不能说早期版本的工作,但解决这个问题的方法是打开一个 zip 文件进行阅读,打开一个新的 zip 文件进行写入,提取第一个的内容,然后在最后添加你的附加组件。完成后用新创建的 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.

仔细检查后,我注意到您正在读取一个以“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 la faire plus courte."
- Blaise Pascal

关于Python 2.6 不喜欢附加到 zip 文件中的现有文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2920793/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com