Python 中的 ZipFile 模块 - 运行时问题

发布于 2024-10-07 07:30:06 字数 2175 浏览 3 评论 0原文

我正在编写一个小脚本,按照一定的结构将多个文件夹压缩为多个 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 个 zip 文件。就这样,大约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。

我的解决方案:编辑有问题的文件以改变其时间戳。也许有一天我会验证是否有更好的解决方案。

感谢大家的帮助。

I'm doing a little script to zip multiple folders in multiple zip files following a certain structure. I've built the structure as a list. Here are some entries:

['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']

Down here are the 2 methods resposible for zipping the files together.

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

The main part os the script is like this:

for i in range(len(myList)):
    zipit(myList[i],os.path.split(myList[i])[1])

I've used numerical indexes because this made the script run well for a larger number of files. Before that, only 2 zipfiles we're written. This way, about 8 make its way to the end. No clue why.

The script simply iterates over the list and compresses each one as a separated zipfile. The problem happens when the size of the list is bigger. I get the following error message.

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')

Do anyone knows what may cause this error?
thanks!

EDIT:

I've used the code provided below to teste the files, the problem were the files with problems with their "last modified" timestamp. For some reason unknown, some of them had the the last modification in the 2049 year.

In that case, the Python zipfile module failed in compressing the files as a ValueError was thrown.

My solution: edit the problematic files to chance their timestamp. Maybe someday I verify is there is a better solution.

Thanks for the help of everyone.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

美煞众生 2024-10-14 07:30:06

与此问题相关的错误报告于 2007 年提交:http://bugs.python.org/issue1760357

该问题是由 Windows 本地时间函数中的错误引起的,时间模块除了抛出 ValueError 之外无能为力。

我解决了这样的问题:

try:
    zip.write(absfilename, zipfilename)
except ValueError:
    os.utime(absfilename, None)
    zip.write(absfilename, zipfilename)

os.utime 行将文件的访问和修改时间更新为当前时间。

A bug report related to this issue was submitted in 2007: http://bugs.python.org/issue1760357

The problem is caused by a bug in the Windows localtime function and there's nothing the time module can do other than throw a ValueError.

I got around the problem like this:

try:
    zip.write(absfilename, zipfilename)
except ValueError:
    os.utime(absfilename, None)
    zip.write(absfilename, zipfilename)

The os.utime line update the file's access and modified times to the current time.

把人绕傻吧 2024-10-14 07:30:06

mtime 是文件上次修改时间的时间戳。因此,对于一个文件来说,它可能在某种程度上是无效的。找出导致该问题的文件,然后调用 os.stat(filename).st_mtime 进行检查。

mtime is a timestamp for when your file was last modified. So, it's probably invalid in some way for one file. Work out what file causes it, then call os.stat(filename).st_mtime to check it.

水中月 2024-10-14 07:30:06

看看这个效果是否更好。至少,您会发现哪个文件出现故障以及原因。

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', '.')

See if this works any better. At a minimum, you'll find out which file is failing and why.

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', '.')
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文