'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 1:[1]
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
Solution 2:[2]
You need to add each file in location on it's own to zip1
.
Add this to the according if
-branch:
for f in os.listdir("location"):
zip1.write("location/"+f, compress_type=zipfile.ZIP_DEFLATED)
Solution 3:[3]
The reason you're not able to add a directory to the zip archive is because zip1.write
is not recursive (It won't add files that are further down the directory tree, only what you explicitly tell it to add). You'll need to use os.walk
to go through all sub-directories and add each file individually:
import os
import zipfile
def zipdir(dir_to_archive, archive_filename):
ziph = zipfile.ZipFile(archive_filename, 'w', zipfile.ZIP_DEFLATED)
for root, dirs, files in os.walk(dir_to_archive):
for file in files:
if file != archive_filename:
ziph.write(os.path.join(root, file))
ziph.close()
os.chdir(dir_path)
zipdir(dir_path, 'Archive.zip')
Note, the above code was adapted from this answer by Mark Byers.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | jofrev |
Solution 3 |