How to Zip a Directory with Python (using zipfile)

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Bertsche
    New Member
    • Nov 2008
    • 3

    How to Zip a Directory with Python (using zipfile)

    I'm relatively new to python, and am trying to zip a directory containing several levels of files and folders. I can use the walk function to name each file in my directory, and I can use zipfile to zip a flat number of files in one folder, but I am having heck of a time trying to zip the whole directory. I want to zip it all to a file called "help.zip", and I want it to retain the original file structure.

    Of my several tries, here is the latest:
    Code:
    import zipfile, os
    
    def main():
        zip = "help3.zip"
        directory = "//groupstore/workgroups/documentation/test"
        toZip(directory)
    
    
    def toZip(directory):
        zippedHelp = zipfile.ZipFile(zip, "w", compression=zipfile.ZIP_DEFLATED )
    
        list = os.listdir(directory)
    
        for entity in list:
            each = os.path.join(directory,entity)
    
            if os.path.isfile(each):
                print each
                zippedHelp.write(each,zipfile.ZIP_DEFLATED)
            else:
                addFolderToZip(zippedHelp,entity)
    
        zippedHelp.close()
    
    #def addFolderToZip(zippedHelp,folder):
    
        for file in folder:
                if os.path.isfile(file):
                    zippedHelp.write(file, os.path.basename(file), zipfile.ZIP_DEFLATED)
                elif os.path.isdir(file):
                    addFolderToZip(zippedHelp,file)
    main()
  • bvdet
    Recognized Expert Specialist
    • Oct 2006
    • 2851

    #2
    Here's another thread that may be relevant: http://bytes.com/forum/thread845051.html

    Comment

    • bvdet
      Recognized Expert Specialist
      • Oct 2006
      • 2851

      #3
      Here's a script that I use to backup the contents of a directory and it's subdirectories. It can easily be adjusted to backup only the directory contents or files with specific extensions. The file path is saved in the archive.
      [code=Python]import zipfile, os

      def makeArchive(fil eList, archive):
      """
      'fileList' is a list of file names - full path each name
      'archive' is the file name for the archive with a full path
      """
      try:
      a = zipfile.ZipFile (archive, 'w', zipfile.ZIP_DEF LATED)
      for f in fileList:
      print "archiving file %s" % (f)
      a.write(f)
      a.close()
      return True
      except: return False

      def dirEntries(dir_ name, subdir, *args):
      '''Return a list of file names found in directory 'dir_name'
      If 'subdir' is True, recursively access subdirectories under 'dir_name'.
      Additional arguments, if any, are file extensions to match filenames. Matched
      file names are added to the list.
      If there are no additional arguments, all files found in the directory are
      added to the list.
      Example usage: fileList = dirEntries(r'H: \TEMP', False, 'txt', 'py')
      Only files with 'txt' and 'py' extensions will be added to the list.
      Example usage: fileList = dirEntries(r'H: \TEMP', True)
      All files and all the files in subdirectories under H:\TEMP will be added
      to the list.
      '''
      fileList = []
      for file in os.listdir(dir_ name):
      dirfile = os.path.join(di r_name, file)
      if os.path.isfile( dirfile):
      if not args:
      fileList.append (dirfile)
      else:
      if os.path.splitex t(dirfile)[1][1:] in args:
      fileList.append (dirfile)
      # recursively access file names in subdirectories
      elif os.path.isdir(d irfile) and subdir:
      print "Accessing directory:", dirfile
      fileList.extend (dirEntries(dir file, subdir, *args))
      return fileList

      if __name__ == '__main__':
      folder = r'D:\Zip_Files\ 611 Lenox'
      zipname = r'D:\Zip_Files\ 611 Lenox\test.zip'
      makeArchive(dir Entries(folder, True), zipname)
      [/code]HTH

      Comment

      • Bertsche
        New Member
        • Nov 2008
        • 3

        #4
        Originally posted by bvdet
        Here's another thread that may be relevant: http://bytes.com/forum/thread845051.html

        Thanks! I appreciate the help!

        Comment

        • Bertsche
          New Member
          • Nov 2008
          • 3

          #5
          Originally posted by bvdet
          Here's a script that I use to backup the contents of a directory and it's subdirectories. It can easily be adjusted to backup only the directory contents or files with specific extensions. The file path is saved in the archive.

          Thank you!! Yay. I used your script to make mine work and I'm getting a better understanding of recursive functions. That was definitely where my hangup had been. Thanks again!!

          Comment

          • jbpseudo
            New Member
            • Feb 2009
            • 1

            #6
            Thanks

            Originally posted by bvdet
            Here's a script that I use to backup the contents of a directory and it's subdirectories. It can easily be adjusted to backup only the directory contents or files with specific extensions. The file path is saved in the archive.
            Thanks, this is just what i was looking for in my pys60 app :D. Thanks again for the help :)

            Comment

            • Nakubu
              New Member
              • Mar 2010
              • 2

              #7
              Shorter, more concise method:

              you can also do this, which is MUCH more concise:

              Code:
              def recursive_zip(zipf, directory, folder=None):
                  list = os.listdir(directory)
              
                  for file in list:
                      if os.path.isfile(file):
                          zipf.write(file, folder, zipfile.ZIP_DEFLATED)
                      elif os.path.isdir(file):
                          recursive_zip(zipf, os.path.join(directory, file), file)
              Last edited by bvdet; Mar 31 '10, 12:53 PM. Reason: Add code tags

              Comment

              • bvdet
                Recognized Expert Specialist
                • Oct 2006
                • 2851

                #8
                Nakubu,

                Thank you for your contribution. Please use code tags when posting code in the future.

                It's not a good idea to use list and file as names of variables. The built-in functions list() and file() will be masked until the objects are deleted.

                I have a question. Is zipf an open file object? It would be helpful to others reading this thread if you would post sample code that creates the file object, calls recursive_zip(), and closes the file object.

                BV - Moderator

                Comment

                • Nakubu
                  New Member
                  • Mar 2010
                  • 2

                  #9
                  here's a revised version:

                  [code=python]
                  def recursive_zip(z ipf, directory, folder=None):
                  nodes = os.listdir(dire ctory)

                  for item in nodes:
                  if os.path.isfile( item):
                  zipf.write(item , folder, zipfile.ZIP_DEF LATED)
                  elif os.path.isdir(i tem):
                  recursive_zip(z ipf, os.path.join(di rectory, item), item)

                  [/code]

                  zipf is an opened zipfile.ZipFile instance. For example:

                  [code=python]
                  zipf = zipfile.ZipFile (zip, "w", compression=zip file.ZIP_DEFLAT ED )
                  path = '/Users/nakubu/some_folder'
                  recursive_zip(z ipf, path) //leave the first folder as None, as path is root.
                  zipf.close()
                  [/code]

                  Comment

                  • Kim Fisher

                    #10
                    revised version of Nakubu's function

                    I found Nakubu's function helpful, but needed to modify it in several ways. Hope this helps someone:
                    Code:
                    def recursive_zip(zipf, directory, folder = ""):
                       for item in os.listdir(directory):
                          if os.path.isfile(os.path.join(directory, item)):
                             zipf.write(os.path.join(directory, item), folder + os.sep + item)
                          elif os.path.isdir(os.path.join(directory, item)):
                             recursive_zip(zipf, os.path.join(directory, item), folder + os.sep + item)

                    Comment

                    • Michael Casile
                      New Member
                      • Jun 2011
                      • 1

                      #11
                      These are all good, but IMHO, os.walk rocks and does the hard stuff for you.

                      Comment

                      Working...