Python - Compress all files in a directory using zipfile module

2.1k views Asked by At

I'm trying to compress all files in a folder (the folder does not have any subdirs) using python zipfile module but can't seem to get the desired output.

I have folderA sitting under F:\Projects\ProjectA\Folders\folderA and my script under F:\Projects\ProjectA\CodeA\zipcode.py. I want to compress all files in folderA such that the resulting zip file is named as folderA.zip under F:\Projects\ProjectA\Folders and with the original file names.

The only issue is that unzipping the result yields Folders\folderA instead of just folderA. It has to do with the relative path of folderA to script but I can't seem to get the desired result.

#zipcode.py
import os
import zipfile

filepath = "F:/Projects/ProjectA/Folders/folderA"

archive = zipfile.ZipFile(os.path.abspath(filepath) + '.zip', 'w')

for root, dirs, files in os.walk(filepath):
        for afile in files:
            archive.write(os.path.relpath(os.path.join(root, afile)))
        archive.close()
1

There are 1 answers

2
Jean-François Fabre On BEST ANSWER

in your loop, change the name of the archive member using arcname parameter:

archive.write(os.path.join(root, afile),arcname=name_in_archive)

Where

name_in_archive = os.path.join(os.path.basename(filepath),afile)

to preserve folderA path.

One thing I'm not sure (depending on versions of python) is that you may have to replace windows backslashes by slashes so the .zip file is portable. Doesn't hurt:

archive.write(os.path.join(root, afile),arcname=name_in_archive.replace(os.sep,"/"))

Note that I have dropped the os.path.relpath call, not needed now since we have full control of the name of the file in the archive.

Also note that converting to absolute path when opening the archive is not necessary. open finds the file if it's relative as well as if it is absolute:

archive = zipfile.ZipFile(os.path.abspath(filepath) + '.zip', 'w')

could just be written

archive = zipfile.ZipFile(filepath + '.zip', 'w')