Python 中的 ZipFile 模块 - 运行时问题
Posted
技术标签:
【中文标题】Python 中的 ZipFile 模块 - 运行时问题【英文标题】:ZipFile module in Python - Runtime problems 【发布时间】:2010-12-13 23:47:32 【问题描述】:我正在编写一个小脚本,以按照一定的结构将多个文件夹压缩到多个 zip 文件中。我已经将结构构建为列表。以下是一些条目:
['E:\Documents\UFSCar\Primeiro Ano\Primeiro Semestre\Cálculo 1',
'E:\Documents\UFSCar\Primeiro Ano\Segundo Semestre\Estatistica',
'E:\Documents\UFSCar\Primeiro Ano\Segundo Semestre\Estruturas Discretas',
'E:\Documents\UFSCar\Primeiro Ano\Segundo Semestre\Introdução à Engenharia']
这里有两种方法可以将文件压缩在一起。
def zipit (path, archname):
# Create a ZipFile Object primed to write
archive = ZipFile(archname, "w", ZIP_DEFLATED) # "a" to append, "r" to read
# Recurse or not, depending on what path is
if os.path.isdir(path):
zippy(path, archive)
else:
archive.write(path)
archive.close()
return "Compression of \""+path+"\" was successful!"
def zippy(path,archive):
paths = os.listdir(path)
for p in paths:
p = os.path.join(path,p)
if os.path.isdir(p):
zippy(p,archive)
else:
archive.write(p)
return
脚本的主要部分是这样的:
for i in range(len(myList)):
zipit(myList[i],os.path.split(myList[i])[1])
我使用了数字索引,因为这使得脚本可以很好地处理大量文件。在此之前,我们只编写了 2 个 zipfile。这样,大约 8 人走到了尽头。不知道为什么。
脚本简单地遍历列表并将每个列表压缩为一个单独的 zip 文件。当列表的大小更大时,就会出现问题。我收到以下错误消息。
Traceback (most recent call last):
File "E:\Documents\UFSCar\zipit.py", line 76, in <module>
zipit(listaDisciplinas[i],os.path.split(listaDisciplinas[i])[1])
File "E:\Documents\UFSCar\zipit.py", line 22, in zipit
zippy(path, archive)
File "E:\Documents\UFSCar\zipit.py", line 11, in zippy
zippy(p,archive)
File "E:\Documents\UFSCar\zipit.py", line 11, in zippy
zippy(p,archive)
File "E:\Documents\UFSCar\zipit.py", line 13, in zippy
archive.write(p)
File "C:\Python27\lib\zipfile.py", line 994, in write
mtime = time.localtime(st.st_mtime)
ValueError: (22, 'Invalid argument')
有谁知道可能导致此错误的原因? 谢谢!
编辑:
我使用下面提供的代码来测试文件,问题是文件的“最后修改”时间戳有问题。出于某种未知的原因,其中一些在 2049 年进行了最后一次修改。
在这种情况下,Python zipfile 模块无法压缩文件,因为抛出了 ValueError。
我的解决方案:编辑有问题的文件以更改其时间戳。也许有一天我会验证是否有更好的解决方案。
感谢大家的帮助。
【问题讨论】:
你能在 zipfile.py 中加入一个打印语句,在这个调用的正上方打印出 st.st_mtime 的值吗? 什么是受影响文件的mtime? 【参考方案1】:2007 年提交了与此问题相关的错误报告:http://bugs.python.org/issue1760357
此问题是由 Windows localtime 函数中的错误引起的,时间模块除了抛出 ValueError 之外无能为力。
我解决了这样的问题:
try:
zip.write(absfilename, zipfilename)
except ValueError:
os.utime(absfilename, None)
zip.write(absfilename, zipfilename)
os.utime 行将文件的访问和修改时间更新为当前时间。
【讨论】:
【参考方案2】:mtime
是您的文件上次修改时间的时间戳。因此,对于一个文件,它可能在某种程度上是无效的。找出是什么文件引起的,然后打电话给os.stat(filename).st_mtime
检查。
【讨论】:
【参考方案3】:看看这是否更好。至少,您会发现哪个文件失败以及失败的原因。
import os
import os.path
from time import localtime
from zipfile import ZipFile, ZIP_DEFLATED
def zipper(zipfilename, directory):
archive = ZipFile(zipfilename, "w", ZIP_DEFLATED)
for root, dirs, files in os.walk(directory):
for f in files:
path = os.path.join(root, f)
try:
archive.write(path)
except ValueError, err:
print "Error compressing %s" % path
s = os.stat(path)
print s.st_mtime
print localtime(s.st_mtime)
print str(err)
archive.close()
if __name__ == '__main__':
zipper('foo.zip', '.')
【讨论】:
我已经尝试了您的代码,但在带有 2098 年时间戳的文件中出现错误。我认为这导致了溢出,因此导致了错误。现在我将尝试使用 7Zip 之类的程序压缩这个文件,看看会发生什么。顺便说一句,你的算法让我检测到错误,但是在压缩文件夹时,它不会在 zipfile 中保留文件夹结构。以上是关于Python 中的 ZipFile 模块 - 运行时问题的主要内容,如果未能解决你的问题,请参考以下文章