在python中压缩文件

Posted

技术标签:

【中文标题】在python中压缩文件【英文标题】:Zipping files in python 【发布时间】:2012-06-28 08:24:40 【问题描述】:

我的程序运行顺利,但我希望将来自 ftp 的文件压缩到我的本地驱动器中

我的问题:调用 main() 函数后只有 1 个文件被压缩

这是我的代码:

主要

import os
import upload
import download
import zipfile
import ConfigParser
import ftputil

def main():
    
    #create a folder Temp on d drive for later use
    path = r'D:\Temp'
    os.mkdir(path)
    
    #parse all the  values at config.ini file
    config = ConfigParser.ConfigParser()
    config.readfp(open('config.ini'))
    server = config.get('main', 'Server')
    username = config.get('main', 'Username')
    password = config.get('main', 'Password')
    uploads = config.get('main', 'Upload folder')
    downloads = config.get('main', 'Download folder')

    #connect to ftp
    ftp = ftputil.FTPHost(server, username, password)

    dirlist = ftp.listdir(downloads)
    
    for list in dirlist:
        ftp.chdir(downloads)
        target = os.path.join(path, list)
        ftp.download(list, target)
        
    
    #########################################################
    #   THis section is where algo fails but the program run#
    ########################################################
    
    #zipping files
    absolute_path = r'D:\Temp'
    dirlist = os.listdir(absolute_path)
    filepath = r'D:\Temp\project2.zip'
    for list in dirlist:
        get_file = os.path.join(absolute_path, list)
        zip_name = zipfile.ZipFile(filepath, 'w')
        zip_name.write(get_file, 'Project2b\\' + list)
        
                
        

if __name__ == '__main__':
    print "cannot be"

【问题讨论】:

你存档是否包含最后一个文件target 您缺少压缩方法,zipfile.ZIP_DEFLATED 如果没有给出文件将不会被压缩。应该是 zipfile.ZipFile(filepath, 'w',zipfile.ZIP_DEFLATED) 来包含压缩 【参考方案1】:

当你这样做时:

for list in dirlist:
        get_file = os.path.join(absolute_path, list)
        zip_name = zipfile.ZipFile(filepath, 'w')
        zip_name.write(get_file, 'Project2b\\' + list)

您为每个要压缩的文件重新创建一个 ZipFile,"w" 模式意味着您从头开始重新创建它。

试试这个(在循环之前创建 zip 文件):

zip_name = zipfile.ZipFile(filepath, 'w')
for list in dirlist:
        get_file = os.path.join(absolute_path, list)
        zip_name.write(get_file, 'Project2b\\' + list)

或者这样,它将以附加模式打开压缩文件:

for list in dirlist:
        get_file = os.path.join(absolute_path, list)
        zip_name = zipfile.ZipFile(filepath, 'a')
        zip_name.write(get_file, 'Project2b\\' + list)

【讨论】:

是的!这行得通!对不起,我是新手!我仍然无法点击最佳答案按钮,请等待 3 分钟。 :D 再次感谢!【参考方案2】:

看看 shutil 模块。有一个使用 shutil.make_archive() 的例子:

http://docs.python.org/library/shutil.html

【讨论】:

我们需要为此使用 zipfile 模块。 :D make_archive() 正在使用 zipfile 模块。恕我直言,这更方便。【参考方案3】:

如果你有很多文件,你可以并行压缩它们:

import zipfile
from pathlib import Path, WindowsPath
from typing import List, Text
import logging
from time import time
from concurrent.futures import ThreadPoolExecutor

logging.basicConfig(
    format="%(asctime)s - %(message)s", datefmt="%H:%M:%S", level=logging.DEBUG
)

PATH = (r"\\some_directory\subdirectory\zipped")


def file_names() -> List[WindowsPath]:
    p = Path(PATH)
    file_names = list(p.glob("./*.csv"))
    logging.info("There are %d files", len(file_names))
    return file_names


def zip_file(file: WindowsPath) -> None:
    zip_file_name = Path(PATH, f"file.stem.zip")
    with zipfile.ZipFile(zip_file_name, "w") as zip:
        zip.write(file, arcname=file.name, compress_type=zipfile.ZIP_DEFLATED)


def main(files: List[Text]) -> None:
    t0 = time()
    number_of_files = len(files)
    with ThreadPoolExecutor() as executor:
        for counter, _ in enumerate(executor.map(zip_file, files), start=1):
            # update progress every 100 files
            if counter % 100 == 0:
                logging.info(
                    "Processed %d/%d. TT: %d:%d",
                    counter,
                    number_of_files,
                    *divmod(int(time() - t0), 60),
                )

    logging.info(
        "Finished zipping %d files. Total time: %d:%d",
        len(files),
        *divmod(int(time() - t0), 60),
    )


if __name__ == "__main__":
    files = file_names()
    main(files)

【讨论】:

【参考方案4】:

最好的方法是在你的 for 循环中加入调试语句,有两种可能性;

一个是第一个forloop只从ftp文件夹下载一个文件

第二个是第一个循环下载所有文件,但第二个循环只压缩其中一个

使用打印语句查看在循环中下载/压缩了哪些文件,祝你好运

【讨论】:

感谢您的建议,我会尝试的。实际上第一个循环没问题,它下载了我的 ftp 中的所有文件,但第二个循环是问题

以上是关于在python中压缩文件的主要内容,如果未能解决你的问题,请参考以下文章

如何在Mac中压缩文件

在java中压缩和解压缩7z文件

如何在 Objective C 中压缩、解压缩文件(arm64 支持)

在Memorystream中压缩和解压缩

如何在android中压缩和解压缩png图像

如何仅使用 Windows 的内置功能从脚本中压缩或解压缩?