简体   繁体   English

使用 zipfile 在 python 中创建一个 zip 文件夹

[英]Create a zip of folders in python using zipfile

My Problem我的问题

I have a folder called my_folder at the following Path /Users/my_user_name/Desktop/my_folder .我在以下路径/Users/my_user_name/Desktop/my_folder有一个名为my_folder的文件夹。 The folder my_folder contains more folders like 323456 , 987654 etc. Those folders contain some content.文件夹my_folder包含更多文件夹,如323456987654等。这些文件夹包含一些内容。 I want to create a zip of all those folders called myzip.zip such that when someone unzips it they see all those folders like 323456 , 987654 at the root.我想为所有这些名为myzip.zip的文件夹创建一个 zip ,这样当有人解压缩它时,他们会在根目录下看到所有这些文件夹,如323456987654

My Code我的代码

import os
from pathlib import Path
from zipfile import ZipFile


DOWNLOAD_DIR = Path("/Users/my_user_name/Desktop/my_folder")
ZIPPED_FILE_DIR = Path("/Users/my_user_name/Desktop/my_zip")


def get_list_of_all_folders(download_dir: Path):
    return [f for f in download_dir.iterdir() if download_dir.is_dir()]


def zip_files():
    folder_list = get_list_of_all_folders(DOWNLOAD_DIR)
    with ZipFile(ZIPPED_FILE_DIR / "my_zip.zip", "w") as zip:
        # writing each file one by one
        for folder in folder_list:
            zip.write(folder)


zip_files()

I have a function called get_list_of_all_folders where it goes to my_folder and gets a list of all the folders inside it that we want to zip.我有一个名为get_list_of_all_folders的 function,它转到my_folder并获取其中我们想要 zip 的所有文件夹的列表。 Then i use that folder_list to zip up each folder as part of my final zip called my_zip.zip .然后我使用该文件夹列表到folder_list上每个文件夹,作为我最终 zip 的一部分,称为my_zip.zip However there is something really wrong with my code and i am not sure what?但是我的代码确实有问题,我不确定是什么? The my_zip.zip is only 35 kb small when i know for a fact i am zipping up content over 2 gigabytes.当我知道我正在压缩超过 2 GB 的内容时, my_zip.zip只有 35 kb 小。

I looked at the zipfile document but did not find much help here as there are not many examples.我查看了 zipfile文档,但在这里没有找到太多帮助,因为示例不多。 I would really appreciate any help here as i am new to python.我非常感谢这里的任何帮助,因为我是 python 的新手。

ZipFile.write expects to be supplied with the name of a file to write to the zip, not a folder. ZipFile.write需要提供要写入 zip 的文件名,而不是文件夹。

You will need to iterate over the files in each folder and call write for each one.您将需要遍历每个文件夹中的文件并为每个文件调用write For example:例如:

from pathlib import Path
from zipfile import ZipFile


DOWNLOAD_DIR = Path("/Users/my_user_name/Desktop/my_folder")
ZIPPED_FILE_DIR = Path("/Users/my_user_name/Desktop/my_zip")


def scan_dir(zip, dir, base_dir):
    for f in dir.iterdir():
        if f.is_dir():
            scan_dir(zip, f, base_dir)
        else:
            # First param is the path to the file, second param is
            # the path to use in the zip and when extracted. I just
            # trim base_dir off the front.
            zip.write(f, str(f)[len(str(base_dir)):])


def zip_files():
    with ZipFile(ZIPPED_FILE_DIR / "my_zip.zip", "w") as zip:
        for f in DOWNLOAD_DIR.iterdir():
            scan_dir(zip, f, DOWNLOAD_DIR)


zip_files()

There's probably a neater way to trim off the base directory, but this was done quickly:)可能有一种更简洁的方法来修剪基本目录,但这很快就完成了:)

You can use: shutil.make_archive你可以使用: shutil.make_archive

Below example taken from:https://docs.python.org/3/library/shutil.html#archiving-example以下示例取自:https://docs.python.org/3/library/shutil.html#archiving-example

>>> import os
>>> from shutil import make_archive
>>> archive_name = os.path.expanduser(os.path.join('~', 'myarchive'))
>>> root_dir = os.path.expanduser(os.path.join('~', '.ssh'))
>>> make_archive(archive_name, 'zip', root_dir)
'/Users/tarek/myarchive.zip'

EDIT:编辑:

Code using ZipFile library使用 ZipFile 库的代码

import zipfile
import os

class ZipUtilities:
    def toZip(self, file, filename):
        zip_file = zipfile.ZipFile(filename, 'w')
        if os.path.isfile(file):
            zip_file.write(file)
        else:
            self.addFolderToZip(zip_file, file)
        zip_file.close()

    def addFolderToZip(self, zip_file, folder):
        for file in os.listdir(folder):
            full_path = os.path.join(folder, file)
            if os.path.isfile(full_path):
                print('File added: ' + str(full_path))
                zip_file.write(full_path)
            elif os.path.isdir(full_path):
                print('Entering folder: ' + str(full_path))
                self.addFolderToZip(zip_file, full_path)

if __name__ == '__main__':
    utilities = ZipUtilities()
    filename = 'newfile.zip'
    directory = 'foldername'
    utilities.toZip(directory, filename)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM