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


当前回答

这是一种现代方法,使用pathlib和上下文管理器。将文件直接放在zip文件中,而不是放在子文件夹中。

def zip_dir(filename: str, dir_to_zip: pathlib.Path):
    with zipfile.ZipFile(filename, 'w', zipfile.ZIP_DEFLATED) as zipf:
        # Use glob instead of iterdir(), to cover all subdirectories.
        for directory in dir_to_zip.glob('**'):
            for file in directory.iterdir():
                if not file.is_file():
                    continue
                # Strip the first component, so we don't create an uneeded subdirectory
                # containing everything.
                zip_path = pathlib.Path(*file.parts[1:])
                # Use a string, since zipfile doesn't support pathlib  directly.
                zipf.write(str(file), str(zip_path))

其他回答

如何在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

假设要压缩当前目录中的所有文件夹(子目录)。

for root, dirs, files in os.walk("."):
    for sub_dir in dirs:
        zip_you_want = sub_dir+".zip"
        zip_process = zipfile.ZipFile(zip_you_want, "w", zipfile.ZIP_DEFLATED)
        zip_process.write(file_you_want_to_include)
        zip_process.close()

        print("Successfully zipped directory: {sub_dir}".format(sub_dir=sub_dir))
# import required python modules
# You have to install zipfile package using pip install

import os,zipfile

# Change the directory where you want your new zip file to be

os.chdir('Type your destination')

# Create a new zipfile ( I called it myfile )

zf = zipfile.ZipFile('myfile.zip','w')

# os.walk gives a directory tree. Access the files using a for loop

for dirnames,folders,files in os.walk('Type your directory'):
    zf.write('Type your Directory')
    for file in files:
        zf.write(os.path.join('Type your directory',file))

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