Обновление для каждого цикла в Python

1

Ниже приведен код 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)
  • 0
    Нет, Data.gdb - это имя базы данных на основе файлов, и это единственный файл, который я хочу заархивировать. Все остальные файлы, которые я не хочу, включены в zip-файл.
  • 0
    Если «Data.gdb» является каталогом, то это должно быть аргументом командной строки для этой программы, и все готово. Программирование не требуется.
Теги:
gis
arcgis

2 ответа

1
Лучший ответ

Лучшим способом перехода по дереву каталогов является 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 в конце: эффект застегивается только на один файл с таким именем, в отличие от zipping all так называемые файлы, которые могут встречаться в дереве (в соответствующих подкаталогах). Если вы знаете только один такой файл, также можете оставить return в (он просто немного ускорит работу). Если вы хотите, чтобы все такие файлы были там более одного, удалите return.

Изменить: получается, что "одна вещь", которую хочет использовать OP, - это каталог , а не файл. В этом случае я бы предложил в качестве простейшего решения:

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
    Привет, Алекс. Я обновил свой вопрос выше, чтобы предоставить более подробную информацию о Data.gdb (это системная папка с несколькими двоичными файлами). Также я закомментировал всю мою функцию zipws и добавил ваш код, а также обновил zipws (inworkspace, zip), чтобы он стал zipws (inworkspace, zip, filename), но когда я его запустил, я получил синтаксическую ошибку. Мысли?
  • 0
    @ Джош, последнее, я просто набрал закрытое имя - редактирование, чтобы исправить. Если вам нужна только директория, а не файл, самое простое ИМХО - искать базовое имя root - так как я все равно редактирую, я покажу новую версию.
Показать ещё 2 комментария
0

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

    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

  • 0
    Data.gdb - это несколько файлов, так как это файловая база данных. Так будет ли это проблемой?
  • 0
    @ Джош: Вы должны обновить свой вопрос, чтобы быть очень конкретным в этом вопросе. Не понятно, что означает это имя. Это "каталог"? Или это "файл"? Пожалуйста, обновите ваш вопрос, чтобы предоставить недостающую информацию.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню