Zipping multiple shapefiles to multiple zip folders

8653
8
05-25-2011 05:39 AM
MatthewMikulin
New Contributor
Hello, I am new to scripting and am working with a piece of code that can zip one shapefile to one zip folder, and would like to know if anyone out there can give me some pointers to converting the code to zip multiple shapefiles (within the same folder) into multiple (separate) zip folders. here is the code I have at the moment:

import zipfile, sys, os, glob

testShapeFile = ("C:/Data/Test.shp"
testZipFile = "C:/Data/Test.zip"

def zipShapefile(inShapefile, newZipFN):
    print 'Starting to Zip '+(inShapefile)+' to '+(newZipFN)
   
    if not (os.path.exists(inShapefile)):
        print inShapefile + ' Does Not Exist'
        return False

    if (os.path.exists(newZipFN)):
        print 'Deleting '+newZipFN
        os.remove(newZipFN)

        if (os.path.exists(newZipFN)):
            print 'Unable to Delete'+newZipFN
            return False
       
    zipobj = zipfile.ZipFile(newZipFN,'w')

    for infile in glob.glob( inShapefile.lower().replace(".shp",".*")):
        print infile
        zipobj.write(infile,os.path.basename(infile),zipfile.ZIP_DEFLATED)

    zipobj.close()

    return True

zipShapefile(testShapeFile,testZipFile)
print "done!"


Any help is greatly appreciated.

Thank you

I noticed the indentation is not correct in my post, but is in my script as it does run, I just wanted to point that out. Thank you again in advance
Tags (2)
8 Replies
DuncanHornby
MVP Notable Contributor
Mathew,

Here is the code you seek, make sure you adjust the myFolder string.

Duncan

import zipfile, sys, os, glob

# Set the folder that contains the ShapeFiles
myFolder = "C:/Scratch/FWS/"

def zipShapefile(myFolder):

    # Check if folder exists
    if not (os.path.exists(myFolder)):
        print myFolder + ' Does Not Exist!'
        return False

    # Get a list of shapefiles
    ListOfShapeFiles = glob.glob(myFolder + '*.shp')

    # Main shapefile loop
    for sf in ListOfShapeFiles:
        print 'Zipping ' + sf

        # Create an output zip file name from shapefile
        newZipFN = sf[:-3] + 'zip'

        # Check if output zipfile exists, delete it
        if (os.path.exists(newZipFN)):
            print 'Deleting '+newZipFN
            os.remove(newZipFN)
            if (os.path.exists(newZipFN)):
                print 'Unable to Delete' + newZipFN
                return False

        # Create zip file object
        zipobj = zipfile.ZipFile(newZipFN,'w')

        # Cycle through all associated files for shapefile adding them to zip file
        for infile in glob.glob( sf.lower().replace(".shp",".*")):
            print 'zipping ' + infile + ' into ' + newZipFN
            if infile.lower() != newZipFN.lower() :
                # Avoid zipping the zip file!
                zipobj.write(infile,os.path.basename(infile),zipfile.ZIP_DEFLATED)

        # Close zipfile
        print 'ShapeFile zipped!'
        zipobj.close()

    # Got here so everything is OK
    return True

# Call function to zip files
b = zipShapefile(myFolder)

if b:
    print "Zipping done!"
else:
    print "An error occurred during zipping."
0 Kudos
LoganPugh
Occasional Contributor III
Just saw Hornbydd's post but thought I'd throw this out there as well. Since you already have a function for zipping a single shapefile, you could create another function that simply calls your original function on each .shp in a specified directory. E.g.:

import zipfile, sys, os, glob

def zipShapefilesInDir(inDir, outDir):
    # Check that input directory exists
    if not os.path.exists(inDir):
        print "Input directory %s does not exist!" % inDir
        return False

    # Check that output directory exists
    if not os.path.exists(outDir):
        # Create it if it does not
        print "Creating output directory %s" %outDir
        os.mkdir(outDir)

    print "Zipping shapefile(s) in folder %s to output folder %s" % (inDir, outDir)

    # Loop through shapefiles in input directory
    for inShp in glob.glob(os.path.join(inDir, "*.shp")):
        # Build the filename of the output zip file
        outZip = os.path.join(outDir, os.path.splitext(os.path.basename(inShp))[0] + ".zip")

        # Zip the shapefile
        zipShapefile(inShp, outZip)
    return True

def zipShapefile(inShapefile, newZipFN):
    print 'Starting to Zip '+(inShapefile)+' to '+(newZipFN)

    # Check that input shapefile exists
    if not (os.path.exists(inShapefile)):
        print inShapefile + ' Does Not Exist'
        return False

    # Delete output zipfile if it already exists
    if (os.path.exists(newZipFN)):
        print 'Deleting '+newZipFN
        os.remove(newZipFN)

    # Output zipfile still exists, exit
    if (os.path.exists(newZipFN)):
        print 'Unable to Delete'+newZipFN
        return False

    # Open zip file object
    zipobj = zipfile.ZipFile(newZipFN,'w')

    # Loop through shapefile components
    for infile in glob.glob( inShapefile.lower().replace(".shp",".*")):
        # Skip .zip file extension
        if os.path.splitext(infile)[1].lower() != ".zip":
            print "Zipping %s" % (infile)
            # Zip the shapefile component
            zipobj.write(infile,os.path.basename(infile),zipfile.ZIP_DEFLATED)

    # Close the zip file object
    zipobj.close()
    return True

# Main method, used when this script is the calling module, otherwise
# you can import this module and call your functions from other modules
if __name__=="__main__":
##    testShapeFile = r"C:\temp\geomTest.shp"
##    testZipFile = r"C:\temp\geomTest.zip"
##    zipShapefile(testShapeFile,testZipFile)
    inDir = r"c:\temp"
    outDir = r"c:\temp\testZipShp"
    zipShapefilesInDir(inDir, outDir)
    print "done!"


You could probably improve it further with some actual error handling (try/except/finally).
ZacharyUhlmann
New Contributor III

I should have held off another 10 months - marked the 10 year anniversary of this post.  It worked!!!  Just changed the print statements into 

fav_fruit = 'cantalope'
print('my favorite fruit is {}'.format(fav_fruit))‍‍

And good to go --> Python 3.6

0 Kudos
MatthewMikulin
New Contributor
Thank you both for your help they work great!
0 Kudos
oluwaseyiogunjobi
New Contributor
Can anyone of you guys/ladies explain the zipping process to a lay map maker. Where in the software do i paste the code? How do i process/run it? My computer knowledge is a notch above basic. Thanks in Advance
0 Kudos
John_S_Wood
New Contributor II

I hope by now you've found your answer, but if not, or someone else needs to know:

Go to 'Geoprocessing' up on the main menu (File, Edit, View, Bookmarks...) bar, when it drops down, go to 'python' and click on it... here is where you will paste your code...

0 Kudos
HemingZhu
Occasional Contributor III
Thank you both for your help they work great!


Just want to share with your guys what i have learned. zipfile.ZipFile(newZipFN,'w') only zip a file whose size is less than 2 GB. To zip a larger file (large raster etc), you need use its overload function like this: zipfile.ZipFile(outZipFile, mode="w", compression=zipfile.ZIP_DEFLATED, allowZip64=True)
0 Kudos
JasonBarnes
New Contributor
I successfully got the confirmation that the files have been zipped, however I can't seem to find the zip files. I searched around and within the input folder in the script and nothing is there. Any advice?

##Update. I hade my path directory wrong - used backslashes rather than forwards slashes. All is well. Thanks for the script!
0 Kudos