Модуль ZipFile в Python - Проблемы во время выполнения - PullRequest
4 голосов
/ 14 декабря 2010

Я делаю небольшой скрипт, чтобы сжать несколько папок в нескольких файлах 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']

Ниже приведены 2 метода, которые можно использовать для объединения файлов.

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

Кто-нибудь знает, что может вызвать эту ошибку? спасибо!

EDIT:

Я использовал приведенный ниже код для тестирования файлов, проблема заключалась в том, что файлы имели проблемы с их «последней измененной» временной меткой. Почему-то неизвестно, у некоторых из них была последняя модификация в 2049 году.

В этом случае модуль zipfile Python не смог сжать файлы, так как был выдан ValueError.

Мое решение: отредактируйте проблемные файлы, чтобы изменить время. Может быть, когда-нибудь я проверю, есть ли лучшее решение.

Спасибо за помощь всем.

Ответы [ 3 ]

4 голосов
/ 26 мая 2011

Отчет об ошибке, связанный с этой проблемой, был представлен в 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 обновляет доступ к файлу и изменяет время до текущего времени.

0 голосов
/ 14 декабря 2010

Посмотрите, работает ли это лучше.Как минимум, вы узнаете, какой файл дает сбой и почему.

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 голосов
/ 14 декабря 2010

mtime - это отметка времени последнего изменения файла.Так что, возможно, это неверно для одного файла.Выясните, какой файл вызывает его, затем вызовите os.stat(filename).st_mtime, чтобы проверить его.

...