如何在Python中创建目录结构的zip存档?


当前回答

如何在Python中创建目录结构的zip存档?

在Python脚本中

在Python 2.7+中,shutil有一个make_archive函数。

from shutil import make_archive
make_archive(
  'zipfile_name', 
  'zip',           # the archive format - or tar, bztar, gztar 
  root_dir=None,   # root for archive - current working dir if None
  base_dir=None)   # start archiving from here - cwd if None too

在这里,压缩的归档文件将命名为zipfile_name.zip。如果base_dir距离root_dir更远,它将排除不在base_dir中的文件,但仍将父目录中的文件归档到root_dir。

我在Cygwin上用2.7测试这个时确实遇到了问题——它需要一个root_dir参数,用于cwd:

make_archive('zipfile_name', 'zip', root_dir='.')

从shell使用Python

您也可以使用zipfile模块从shell中使用Python执行此操作:

$ python -m zipfile -c zipname sourcedir

其中zipname是所需目标文件的名称(如果需要,请添加.zip,它不会自动执行),sourcedir是目录的路径。

压缩Python(或者只是不需要父目录):

如果您试图用__init__.py和__main__.py压缩一个python包,并且不需要父目录

$ python -m zipfile -c zipname sourcedir/*

And

$ python zipname

将运行程序包。(请注意,不能将子包作为压缩存档的入口点运行。)

压缩Python应用程序:

如果您有python3.5+,并且特别想压缩Python包,请使用ziapp:

$ python -m zipapp myapp
$ python myapp.pyz

其他回答

要保留要归档的父目录下的文件夹层次结构,请执行以下操作:

import glob
import os
import zipfile

with zipfile.ZipFile(fp_zip, "w", zipfile.ZIP_DEFLATED) as zipf:
    for fp in glob(os.path.join(parent, "**/*")):
        base = os.path.commonpath([parent, fp])
        zipf.write(fp, arcname=fp.replace(base, ""))

如果需要,可以将其更改为使用pathlib进行文件globbing。

要将mydirectory的内容添加到新的zip文件中,包括所有文件和子目录:

import os
import zipfile

zf = zipfile.ZipFile("myzipfile.zip", "w")
for dirname, subdirs, files in os.walk("mydirectory"):
    zf.write(dirname)
    for filename in files:
        zf.write(os.path.join(dirname, filename))
zf.close()

试试下面的一个。它对我有用。

import zipfile, os
zipf = "compress.zip"  
def main():
    directory = r"Filepath"
    toZip(directory)
def toZip(directory):
    zippedHelp = zipfile.ZipFile(zipf, "w", compression=zipfile.ZIP_DEFLATED )

    list = os.listdir(directory)
    for file_list in list:
        file_name = os.path.join(directory,file_list)

        if os.path.isfile(file_name):
            print file_name
            zippedHelp.write(file_name)
        else:
            addFolderToZip(zippedHelp,file_list,directory)
            print "---------------Directory Found-----------------------"
    zippedHelp.close()

def addFolderToZip(zippedHelp,folder,directory):
    path=os.path.join(directory,folder)
    print path
    file_list=os.listdir(path)
    for file_name in file_list:
        file_path=os.path.join(path,file_name)
        if os.path.isfile(file_path):
            zippedHelp.write(file_path)
        elif os.path.isdir(file_name):
            print "------------------sub directory found--------------------"
            addFolderToZip(zippedHelp,file_name,path)


if __name__=="__main__":
    main()

使用shutil,它是python标准库集的一部分。使用shutil非常简单(参见下面的代码):

第一个参数:结果zip/tar文件的文件名,第二个参数:zip/tar,第三个参数:目录名

代码:

import shutil
shutil.make_archive('/home/user/Desktop/Filename','zip','/home/username/Desktop/Directory')

好吧,在阅读了这些建议之后,我想出了一个非常类似的方法,它可以在2.7.x中工作,而不会创建“有趣”的目录名(绝对类似的名称),并且只会在zip中创建指定的文件夹。

或者只是为了以防万一,您需要在zip中包含一个包含所选目录内容的文件夹。

def zipDir( path, ziph ) :
 """
 Inserts directory (path) into zipfile instance (ziph)
 """
 for root, dirs, files in os.walk( path ) :
  for file in files :
   ziph.write( os.path.join( root, file ) , os.path.basename( os.path.normpath( path ) ) + "\\" + file )

def makeZip( pathToFolder ) :
 """
 Creates a zip file with the specified folder
 """
 zipf = zipfile.ZipFile( pathToFolder + 'file.zip', 'w', zipfile.ZIP_DEFLATED )
 zipDir( pathToFolder, zipf )
 zipf.close()
 print( "Zip file saved to: " + pathToFolder)

makeZip( "c:\\path\\to\\folder\\to\\insert\\into\\zipfile" )