在Python中更新For Each循环
下面的Python代码可以把一组文件压缩成一个文件。我只需要一个叫“Data”的文件地理数据库(就是一种基于文件的数据库),那么我该如何修改这个循环,只包含这个叫Data的文件地理数据库呢?更具体地说,文件地理数据库是以系统文件夹的形式存储的,里面包含一些二进制文件,用来存储和管理空间数据。所以我需要的是整个叫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 个回答
0
从这一行开始:
zipws(inworkspace, 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
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
:这样做的结果是只压缩一个特定名字的文件,而不是压缩树中所有同名的文件(包括它们各自的子文件夹里的)。如果你知道只有一个这样的文件,那就可以保留 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
再次猜测一下,你到底想用什么来作为你的压缩包名称,这一点还是个谜。