Обновление для каждого цикла в Python - PullRequest
1 голос
/ 25 августа 2010

Код Python ниже берет список файлов и архивирует их.Единственная Файловая база геоданных (Файловая база данных), которая мне нужна, называется «Данные», так как я могу изменить цикл, включив в него только файловую базу данных под названием Данные?Точнее, файловая база геоданных хранится как системная папка, которая содержит двоичные файлы, которые хранят пространственные данные и управляют ими.Поэтому мне нужна вся системная папка с именем Data.gdb.

Большое спасибо

#**********************************************************************
# 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)

Ответы [ 2 ]

1 голос
/ 26 августа 2010

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

Итак:

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

Я не уверен, что захватил всю логику, с которой вы хотите определить два аргумента, до zip.write (для меня это не очевидно из вашего кода), но если нет, то это должно быть легко настроить .

Кроме того, я не уверен, хотите ли вы, чтобы return в конце: эффект архивирует только один файл с таким именем, в отличие от архивирования всех файлов. назван так, что может встречаться в дереве (в соответствующих подкаталогах). Если вы знаете, что есть только один такой файл, то можете также оставить return (это только немного ускорит процесс). Если вы хотите, чтобы все такие файлы были более одного, удалите return.

Редактировать : получается, что «одна вещь», которую хочет ОП - это каталог , а не файл. В этом случае я бы предложил в качестве самого простого решения:

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

снова с похожим предположением относительно полной тайны, что именно это является , которое вы хотите использовать для своего имени архива.

0 голосов
/ 26 августа 2010

Начните с этой строки:

    zipws(inworkspace, zip)

Вы не хотите использовать эту функцию для создания ZIP-файла из нескольких файлов.Похоже, вы хотите создать zip-файл только с одним участником.

Замените его следующим.

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

Удалите функцию zipws, которую вы - по-видимому - не 'не хочу использовать.

Прочтите это, это может помочь: http://docs.python.org/library/zipfile.html

...