Python中的ZipFile模块 - 运行时问题
我正在写一个小脚本,用来把多个文件夹压缩成多个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])
我使用了数字索引,因为这样可以让脚本在处理更多文件时运行得更好。之前只写出了两个zip文件,而现在大约能生成八个,不知道为什么会这样。
这个脚本简单地遍历列表,把每个文件夹压缩成一个单独的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错误。
我的解决办法是编辑那些有问题的文件,修改它们的时间戳。也许有一天我会再看看有没有更好的解决方案。
感谢大家的帮助。
3 个回答
0
看看这样是否能更好地解决问题。至少,你会知道哪个文件出错了,以及为什么出错。
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', '.')
0
mtime
是一个时间戳,表示你的文件最后一次被修改的时间。所以,可能有某个文件的这个时间戳不太对。你需要找出是哪个文件出了问题,然后用 os.stat(filename).st_mtime
来检查一下它的修改时间。
4
关于这个问题,有个错误报告是在2007年提交的:http://bugs.python.org/issue1760357
这个问题是因为Windows的localtime函数里有个bug,时间模块除了抛出一个ValueError错误,别无他法。
我这样解决了这个问题:
try:
zip.write(absfilename, zipfilename)
except ValueError:
os.utime(absfilename, None)
zip.write(absfilename, zipfilename)
os.utime这一行代码是用来把文件的访问时间和修改时间更新为当前时间的。