2010-12-13 51 views
4

Je crée un petit script pour compresser plusieurs dossiers dans plusieurs fichiers zip suivant une certaine structure. J'ai construit la structure comme une liste. Voici quelques entrées:Module ZipFile en Python - Problèmes d'exécution

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

Voici les deux méthodes permettant de compresser les fichiers ensemble.

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 

La partie principale os le script est comme ceci:

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

Je l'ai utilisé des index numériques car cela fait le script exécuté bien pour un plus grand nombre de fichiers. Avant cela, seulement 2 fichiers zip sont écrits. De cette façon, environ 8 font leur chemin jusqu'à la fin. Aucune idée pourquoi.

Le script parcourt simplement la liste et compresse chacun d'eux sous la forme d'un fichier zip séparé. Le problème se produit lorsque la taille de la liste est plus grande. Je reçois le message d'erreur suivant.

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

Est-ce que quelqu'un sait ce qui peut causer cette erreur? merci!

EDIT:

Je l'ai utilisé le code fourni ci-dessous pour TESTE les fichiers, le problème était les fichiers ayant des problèmes avec leur horodatage « Dernière modification ». Pour une raison inconnue, certains d'entre eux ont eu la dernière modification en 2049 année.

Dans ce cas, le module zipfile Python n'a pas pu compresser les fichiers lorsqu'une erreur ValueError a été levée.

Ma solution: éditer les fichiers problématiques au hasard de leur horodatage. Peut-être qu'un jour je vérifierai qu'il y a une meilleure solution.

Merci pour l'aide de tout le monde.

+1

Pouvez-vous mettre une instruction d'impression dans zipfile.py, en imprimant la valeur de st.st_mtime juste au-dessus de cet appel? –

+1

Quel est le mtime du fichier affecté? –

Répondre

4

Un rapport de bug lié à cette question a été soumise en 2007: http://bugs.python.org/issue1760357

Le problème est causé par un bogue dans la fonction localtime Windows et il n'y a rien le module de temps peut faire autre que jeter un ValueError.

Je suis arrivé autour du problème comme celui-ci:

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

La ligne de os.utime mettre à jour l'accès du fichier et les temps modifiés à l'heure actuelle.

0

mtime est l'horodatage de la dernière modification de votre fichier. Donc, il est probablement invalide d'une manière ou d'une autre pour un fichier. Déterminez quel fichier le provoque, puis appelez os.stat(filename).st_mtime pour le vérifier.

0

Voyez si cela fonctionne mieux. Au minimum, vous découvrirez quel fichier échoue et pourquoi.

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

J'ai essayé votre code et j'ai reçu une erreur dans un fichier avec l'horodatage de l'année 2098. Je pense que cela a provoqué un débordement et, par conséquent, l'erreur.Maintenant, je vais essayer de compresser ce fichier avec un programme comme 7Zip et voir ce qu'il se passe. En passant, votre algorithme m'a fait détecter l'erreur, mais lors de la compression d'un dossier, il ne conserve pas la structure du dossier dans le fichier zip. –