10

Is it possible to retrieve the size of a shapefile using python and arcpy? If so, how?

  • 2
    Do you mean the amount of features? The area covered? The physical file size? – MaryBeth Dec 17 '15 at 20:14
  • os.path.getsize(path) – gene Dec 17 '15 at 20:14
  • yes, the physical file size. Sorry. Thank you @gene – John Dec 17 '15 at 20:19
  • @gene Another silly question. os.path.getsize() returns a integer. is the default in KB's? – John Dec 17 '15 at 20:21
  • 1
    1kB = 1024 bytes, divide bytes by 1024 to obtain kilobytes (or was that kibibytes, just to confuse things). Likewise there's 1024kB in a MB (MiB), 1024 MB in 1 GB (GiB). Note that the size of the shape isn't all of the shapefile there's DBF, SHX at least and bound to be much more - you should add up all those files to obtain the true size on disc. – Michael Stimson Dec 17 '15 at 22:25
14

Iterate through all files in the shapefile directory with a valid shapefile extension and add their sizes together. The os module is helpful for this task. Here's a function that returns the size of all shapefile files associated with an input shapefile in bytes. Use the full path of the shapefile as your input.

import os

def ShpSize (inShp):
    #standardize lowercase
    inShp = inShp.lower ()
    #shapefile extensions
    extensions = [".shp",
                  ".shx",
                  ".dbf",
                  ".sbn",
                  ".sbx",
                  ".fbn",
                  ".fbx",
                  ".ain",
                  ".aih",
                  ".atx",
                  ".ixs",
                  ".mxs",
                  ".prj",
                  ".xml",
                  ".cpg"]

    #shape file name without directory
    shpName = os.path.basename (inShp)
    #shape file name without .shp extension
    shpFlName = os.path.splitext(shpName)[0]

    #size set to zero
    size = 0
    #directory of shapefile
    shpDir = os.path.dirname (inShp)
    #iterate directory files
    for fl in os.listdir (shpDir):
        #standardize lowercase
        fl = fl.lower ()
        #skip file names that don't match shapefile
        flName = os.path.splitext(fl)[0]
        if not flName == shpFlName:
            #special case: .shp.xml file
            if not fl == shpFlName + ".shp.xml":
                continue
        #skip file names without proper extension
        ext = os.path.splitext(fl)[1]
        if not ext in extensions:
            continue
        #get size
        flFullPath = os.path.join (shpDir, fl)
        size += os.path.getsize (flFullPath)

    return size
  • 6
    Instead of listing all the files in shpDir, you can use glob.glob(shpFlName + "*") to only return files that have the same basename. Then it's just a filter on valid extensions. – Paul Dec 17 '15 at 20:56
  • That's true @Paul, glob is really handy however Emils' solution is native python and absolutely correct. The glob method should only be a side note as, in certain situations, users can't just install 3rd party software.. I would only support an answer that requires a 3rd party installation if there was no viable (or realistic) way of doing it in native python. – Michael Stimson Dec 17 '15 at 22:30
  • @MichaelMiles-Stimson glob is native, yea? – Emil Brundage Dec 17 '15 at 22:54
  • I don't think it is, I've got it and use it frequently but I'm semi-sure I had to download it.. I put it on my list of required plugins for a new installation before pyWin32. It may be that later versions come bundled, as with numpy, that would also make sense. I can't access a raw install to see if glob is there, having put it on the list to be installed it's always there; perhaps someone with a fresh/raw install of python could attest to that. – Michael Stimson Dec 17 '15 at 23:02
  • 1
    @MichaelMiles-Stimson - glob is in the standard python library - docs.python.org/2/library/glob.html and has been for a very very long time – user2856 Dec 18 '15 at 0:10
2

You can use a generator expression to efficiently find the shapefile size (i.e. including all associated files). The following method uses built-in Python 2.7 functionality.

import os, glob

ws = r'C:\path\to\your\shapefiles'  # input workspace

shapefiles = glob.glob(os.path.join(ws, "*.shp")) # List all .shp files

for shapefile in shapefiles:
    s = sum([os.stat(x).st_size for x in glob.glob(shapefile.split(".")[0] + "*")])
    print "The file size for %s is %s bytes or %s kb" % (shapefile, s, (float(s)/1000))

The generator expression does the following:

  1. List all of the associated files of a shapefile. In this case, strip off the ".shp" extension from the path and use glob with the path and wildcard * to list all of the associated files
  2. Get the file sizes in bytes using os.stat
  3. Sum them using the generator sum([...]).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.