How to compress folders using zipfile python

╄→гoц情女王★ 提交于 2020-01-30 08:18:27

问题


So 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")

EDIT

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


回答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



回答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)



回答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.



来源:https://stackoverflow.com/questions/59933596/how-to-compress-folders-using-zipfile-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!