2010-08-25 7 views
1

Le code python ci-dessous prend une liste de fichiers et les zippe. La seule géodatabase de fichier (base de données basée sur un fichier) dont j'ai besoin est appelée "Données". Comment puis-je modifier la boucle pour inclure uniquement la base de données basée sur les fichiers appelée Données? Pour être plus précis, une géodatabase fichier est stockée sous la forme d'un dossier système contenant des fichiers binaires qui stockent et gèrent des données spatiales. J'ai donc besoin de tout le dossier système appelé Data.gdb.Mise à jour d'une boucle pour chaque boucle en Python

Merci beaucoup

#********************************************************************** 
# Description: 
# Zips the contents of a folder, file geodatabase or ArcInfo workspace 
# containing coverages into a zip file. 
# Parameters: 
# 0 - Input workspace 
# 1 - Output zip file. It is assumed that the caller (such as the 
#  script tool) added the .zip extension. 
# 
#********************************************************************** 

# Import modules and create the geoprocessor 
import sys, zipfile, arcgisscripting, os, traceback 
gp = arcgisscripting.create() 

# Function for zipping files 
def zipws(path, zip): 
    isdir = os.path.isdir 

    # Check the contents of the workspace, if it the current 
    # item is a directory, gets its contents and write them to 
    # the zip file, otherwise write the current file item to the 
    # zip file 
    # 
    for each in os.listdir(path): 
     fullname = path + "/" + each 
     if not isdir(fullname): 
      # If the workspace is a file geodatabase, avoid writing out lock 
      # files as they are unnecessary 
      # 
      if not each.endswith('.lock'): 
       # gp.AddMessage("Adding " + each + " ...") 
       # Write out the file and give it a relative archive path 
       # 
       try: zip.write(fullname, each) 
       except IOError: None # Ignore any errors in writing file 
     else: 
      # Branch for sub-directories 
      # 
      for eachfile in os.listdir(fullname): 
       if not isdir(eachfile): 
        if not each.endswith('.lock'): 
         # gp.AddMessage("Adding " + eachfile + " ...") 
         # Write out the file and give it a relative archive path 
         # 
         try: zip.write(fullname + "/" + eachfile, \ 
             os.path.basename(fullname) + "/" + eachfile) 
         except IOError: None # Ignore any errors in writing file 


if __name__ == '__main__': 
    try: 
     # Get the tool parameter values 
     # 
     inworkspace = sys.argv[1] 
     outfile = sys.argv[2]  

     # Create the zip file for writing compressed data 
     # 
     zip = zipfile.ZipFile(outfile, 'w', zipfile.ZIP_DEFLATED) 
     zipws(inworkspace, zip) 
     zip.close() 

     # Set the output derived parameter value for models 
     # 
     gp.setparameterastext(1, outfile) 
     gp.AddMessage("Zip file created successfully") 

    except: 
     # Return any python specific errors as well as any errors from the geoprocessor 
     # 
     tb = sys.exc_info()[2] 
     tbinfo = traceback.format_tb(tb)[0] 
     pymsg = "PYTHON ERRORS:\nTraceback Info:\n" + tbinfo + "\nError Info:\n " + \ 
       str(sys.exc_type)+ ": " + str(sys.exc_value) + "\n" 
     gp.AddError(pymsg) 

     msgs = "GP ERRORS:\n" + gp.GetMessages(2) + "\n" 
     gp.AddError(msgs) 
+0

Non, Data.gdb est le nom de la base de données à base de fichiers et qui est le seul fichier que je veux zippé. Tous les autres fichiers que je ne veux pas inclus dans le fichier zip. – Josh

+0

Si 'Data.gdb' est un répertoire, alors cela devrait être l'argument de la ligne de commande pour ce programme et vous avez terminé. Aucune programmation requise. –

Répondre

1

La meilleure façon de marcher sur un arbre de répertoire est os.walk - la séparation ne fichier/dir pour vous, et fait aussi la récursion vers les sous-répertoires pour vous.

Alors:

def zipws(path, zip, filename='Data.gdb'): 
    for root, dirs, files in os.walk(path): 
    if filename in files: 
     zip.write(os.path.join(root, filename), 
       os.path.join(os.path.basename(root), filename)) 
     return 

Je ne suis pas certain que je l'ai capturé toute la logique avec laquelle vous voulez déterminer les deux arguments à zip.write (ce n'est pas évident pour moi de votre code), mais, si non, cela devrait être facile à régler.

Aussi, je ne sais pas si vous voulez que return à la fin: l'effet est passer comme un éclair que un fichier nommé de cette façon, par opposition à passer comme un éclair tous fichiers nommés de cette façon qui peut se produire dans l'arbre (dans leurs sous-répertoires respectifs). Si vous savez qu'il n'y a qu'un seul fichier, laissez le return (cela accélérera un peu les choses). Si vous voulez tous ces fichiers lorsqu'il y en a plusieurs, supprimez le return.

Modifier: se avère que la « chose » l'OP veut est un répertoire , pas un fichier. Dans ce cas, je suggère, comme la solution la plus simple:

def zipws(path, zip, dirname='Data.gdb'): 
    for root, dirs, files in os.walk(path): 
    if os.path.basename(root) != dirname: continue 
    for filename in files: 
     zip.write(os.path.join(root, filename), 
       os.path.join(dirname, filename)) 
    return 

à nouveau avec une estimation similaire WRT le mystère total de quoi exactement il est que vous souhaitez utiliser pour votre archive nom.

+0

Salut Alex - J'ai mis à jour ma question ci-dessus afin de fournir plus de détails sur Data.gdb (c'est un dossier système avec plusieurs fichiers binaires). J'ai aussi commenté toute ma fonction zipws et j'ai ajouté votre code et zipws mis à jour (inworkspace, zip) pour être zipws (inworkspace, zip, nom de fichier) mais quand je l'ai couru, j'ai une erreur de syntaxe.Pensées? – Josh

+0

@Josh, re ce dernier, j'ai juste fait un typoed fermé un paren-édition fermée à réparer. Si la seule chose que vous cherchez est un répertoire, pas un fichier, le plus simple à mon humble avis est de rechercher le nom de base de la racine - depuis que je suis en train de modifier, je vais montrer la nouvelle version. –

+0

Beau travail Alex. Ça a marché. – Josh

0

Démarrer à cette ligne:

zipws(inworkspace, zip) 

Vous ne voulez pas utiliser cette fonction pour construire le fichier zip à partir de fichiers multiples. Il semble que vous souhaitiez créer un fichier zip avec un seul membre.

Remplacez-le par ceci.

 try: 
     zip.write(os.path.join('.', 'Data.gdb')) 
    except IOError: 
     pass # Ignore any errors in writing file 

Jeter la fonction zipws que vous - apparemment - ne voulez pas utiliser.

Lire cela, il peut aider: http://docs.python.org/library/zipfile.html

+0

Data.gdb est plusieurs fichiers car il s'agit d'une base de données basée sur un fichier. Est-ce que ce sera un problème? – Josh

+0

@Josh: Vous devriez ** mettre à jour ** votre question pour être très précis sur ce point. Ce n'est pas clair ce que ce nom signifie. Est-ce un "répertoire"? Ou est-ce un "fichier"? Veuillez mettre à jour votre question pour fournir les informations manquantes. –

+0

mis à jour, merci – Josh