如何使用 zipfile 压缩文件夹?

How to compress folders using zipfile?

到目前为止,我的程序能够成功添加和压缩与 test.py 位于同一目录中的文件,但在同一目录中还有一个名为 location 的文件夹,其中包含其他文件说 citynames.txt 当我做一个简单的 zip.write (else 块中使用的逻辑)时会发生什么 location 被添加到 zip 文件但是它是空的,它不是出于某种原因,其中包含 citynames.txt 请帮我添加文件夹本身?

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

假设位置还有更多子文件夹如何将文件压缩到其中?

您需要将 位置 中的每个文件单独添加到 zip1
将此添加到相应的 if-分支:

for f in os.listdir("location"):
    zip1.write("location/"+f, compress_type=zipfile.ZIP_DEFLATED)

您无法将目录添加到 zip 存档的原因是 zip1.write 不是递归的(它不会添加目录树下方的文件,只会添加您明确告诉的文件它添加)。您需要使用 os.walk 遍历所有子目录并单独添加每个文件:

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')

注意,以上代码改编自this answer by Mark Byers

清单[Python 3.Docs]: zipfile - Work with ZIP archives.

您代码中的(主要)问题是您将 continue 误认为是 break。这样,当遇到 test.py 时,它后面的所有项目将被忽略,因为 break 退出循环。

这是一个使用 [Python 3.Docs]: glob.iglob(pathname, *, recursive=False) 递归到子目录并在存档中添加文件的变体。

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

输出:

e:\Work\Dev\Whosebug\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\Whosebug\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\Whosebug\q059933596>dir *.zip
 Volume in drive E is SSD0-WORK
 Volume Serial Number is AE9E-72AC

 Directory of e:\Work\Dev\Whosebug\q059933596

20/01/27  20:13               547 archive.zip
               1 File(s)            547 bytes
               0 Dir(s)  113,094,475,776 bytes free