4

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()
Dharman
  • 30,962
  • 25
  • 85
  • 135
Riz_K
  • 71
  • 4

1 Answers1

1

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')
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
  • I actually want the output zip file to contain a folder named folderA with all the files residing in it. The above will write the files directly to the zip file. – Riz_K Jan 03 '17 at 20:39
  • @Riz_K: true for my first answer, but my edit added `name_in_archive = os.path.join(os.path.basename(filepath),afile)`. This adds `folderA` prefix to all your files. The important point is that you know how to control the names of the files in your archive. – Jean-François Fabre Jan 03 '17 at 20:41