Search code examples
pythonpython-2.7python-zipfile

How to compress folders using zipfile?


My program so far is successfully able to add and compress files which are present in the same directory as test.py but there is also a folder named location in the same directory which contains additional files say citynames.txt What happens is when I do a simple zip.write (The logic used in else block) location is added to the zip file however its empty that is it does not contain citynames.txt inside it for some reason please help me add the folder itself somehow?

import os
import zipfile
import shutil
dir_path = os.path.dirname(os.path.realpath(__file__))  #holds the directory where script is located
os.chdir(dir_path)                                      #Changes to directory where script is located
fp=os.listdir(dir_path)                                 #file pointer

directory_size=len(os.listdir(dir_path))

zip1=zipfile.ZipFile('Archive.zip','w')

for i in range(directory_size) :
   if fp[i]=='test.py':
      break
   if fp[i]=='location':
      #Some code needs to be added here to write all the contents of folder "location" into 
       "Archive.zip"

   else:
       zip1.write(fp[i],compress_type=zipfile.ZIP_DEFLATED)

print("Process completed")

Assuming location has further sub-folders how to zip the files inside them aswell?


Solution

  • Listing [Python 3.Docs]: zipfile - Work with ZIP archives.

    The (main) problem in your code is that you're mistaking continue by break. That way, when test.py is encountered, all the items after it will be ignored, as break exits the loop.

    Here's a variant that recurses into subdirectories using [Python 3.Docs]: glob.iglob(pathname, *, recursive=False) and adds files in the archive.

    code00.py:

    #!/usr/bin/env python
    
    import sys
    import os
    import glob
    import zipfile
    
    
    def main(*argv):
        archive_name = "archive.zip"
        dir_path = os.path.dirname(os.path.realpath(__file__))
        dir_path_len = len(dir_path) + len(os.path.sep)
        with zipfile.ZipFile(archive_name, mode="w", compression=zipfile.ZIP_DEFLATED) as zf:
            for file_name in glob.iglob(os.path.join(dir_path, "**"), recursive=True):
                if os.path.isdir(file_name):
                    continue
                member_name = file_name[dir_path_len:]
                if member_name in [
                    os.path.basename(__file__),
                    archive_name,
                ]:
                    continue
                print(member_name)
                zf.write(file_name, member_name)
    
    
    if __name__ == "__main__":
        print("Python {0:s} {1:d}bit on {2:s}\n".format(" ".join(item.strip() for item in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform))
        main(*sys.argv[1:])
        print("\nDone.")
    

    Output:

    e:\Work\Dev\StackOverflow\q059933596>tree /f /a
    Folder PATH listing for volume SSD0-WORK
    Volume serial number is AE9E-72AC
    E:.
    |   code00.py
    |   file0.txt
    |
    \---locations
        |   location0.tzt
        |   location1.txt
        |
        \---subdir0
                subdir0file0.txt
    
    
    e:\Work\Dev\StackOverflow\q059933596>"e:\Work\Dev\VEnvs\py_pc064_03.07.06_test0\Scripts\python.exe" code00.py
    Python 3.7.6 (tags/v3.7.6:43364a7ae0, Dec 19 2019, 00:42:30) [MSC v.1916 64 bit (AMD64)] 64bit on win32
    
    file0.txt
    locations\location0.tzt
    locations\location1.txt
    locations\subdir0\subdir0file0.txt
    
    Done.
    
    e:\Work\Dev\StackOverflow\q059933596>dir *.zip
     Volume in drive E is SSD0-WORK
     Volume Serial Number is AE9E-72AC
    
     Directory of e:\Work\Dev\StackOverflow\q059933596
    
    20/01/27  20:13               547 archive.zip
                   1 File(s)            547 bytes
                   0 Dir(s)  113,094,475,776 bytes free