我该如何在Python中创建一个包含目录结构的zip压缩文件?
os.path.join()
可能会轻松返回不兼容 POSIX 的路径。在 Linux 上使用任何常见的存档软件处理它时,生成的归档文件将包含字面上带有反斜杠的文件名,这不是您想要的结果。因此,应该改用 path.as_posix()
来替换 arcname
参数!import zipfile
from pathlib import Path
with zipfile.ZipFile("archive.zip", "w", zipfile.ZIP_DEFLATED) as zf:
for path in Path("include_all_of_this_folder").rglob("*"):
zf.write(path, path.as_posix())
压缩文件或目录树(包括目录及其子目录)。
from pathlib import Path
from zipfile import ZipFile, ZIP_DEFLATED
def make_zip(tree_path, zip_path, mode='w', skip_empty_dir=False):
with ZipFile(zip_path, mode=mode, compression=ZIP_DEFLATED) as zf:
paths = [Path(tree_path)]
while paths:
p = paths.pop()
if p.is_dir():
paths.extend(p.iterdir())
if skip_empty_dir:
continue
zf.write(p)
mode='a'
,要创建新的归档文件,请传递 mode='w'
(以上是默认值)。因此,假设您想将3个不同的目录树打包到同一个归档文件中。make_zip(path_to_tree1, path_to_arch, mode='w')
make_zip(path_to_tree2, path_to_arch, mode='a')
make_zip(path_to_file3, path_to_arch, mode='a')
# 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))
在阅读了建议之后,我想出了一种非常相似的方法,可以在不创建“有趣”的目录名称(类似绝对路径的名称)的情况下与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" )
创建 zip 文件的函数。
def CREATEZIPFILE(zipname, path):
#function to create a zip file
#Parameters: zipname - name of the zip file; path - name of folder/file to be put in zip file
zipf = zipfile.ZipFile(zipname, 'w', zipfile.ZIP_DEFLATED)
zipf.setpassword(b"password") #if you want to set password to zipfile
#checks if the path is file or directory
if os.path.isdir(path):
for files in os.listdir(path):
zipf.write(os.path.join(path, files), files)
elif os.path.isfile(path):
zipf.write(os.path.join(path), path)
zipf.close()
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))
我通过整合Mark Byers的解决方案和Reimund以及Morten Zilmer的评论(相对路径和包括空目录)来准备一个函数。作为最佳实践,ZipFile的文件构建中使用了with
。
该函数还准备了一个默认的zip文件名,其中包含压缩目录名称和'.zip'扩展名。因此,它只需要一个参数:要压缩的源目录。
import os
import zipfile
def zip_dir(path_dir, path_file_zip=''):
if not path_file_zip:
path_file_zip = os.path.join(
os.path.dirname(path_dir), os.path.basename(path_dir)+'.zip')
with zipfile.ZipFile(path_file_zip, 'wb', zipfile.ZIP_DEFLATED) as zip_file:
for root, dirs, files in os.walk(path_dir):
for file_or_dir in files + dirs:
zip_file.write(
os.path.join(root, file_or_dir),
os.path.relpath(os.path.join(root, file_or_dir),
os.path.join(path_dir, os.path.pardir)))
shutil
时,请注意在base_name
参数中包含输出目录路径。import shutil
shutil.make_archive(
base_name=output_dir_path + output_filename_without_extension,
format="zip",
root_dir=input_root_dir)
import zipfile
def zipFolder(toZipFolder, outputZipFile):
"""
zip/compress a whole folder/directory to zip file
"""
print("Zip for foler %s" % toZipFolder)
with zipfile.ZipFile(outputZipFile, 'w', zipfile.ZIP_DEFLATED) as zipFp:
for dirpath, dirnames, filenames in os.walk(toZipFolder):
# print("%s" % ("-"*80))
# print("dirpath=%s, dirnames=%s, filenames=%s" % (dirpath, dirnames, filenames))
# print("Folder: %s, Files: %s" % (dirpath, filenames))
for curFileName in filenames:
# print("curFileName=%s" % curFileName)
curFilePath = os.path.join(dirpath, curFileName)
# print("curFilePath=%s" % curFilePath)
fileRelativePath = os.path.relpath(curFilePath, toZipFolder)
# print("fileRelativePath=%s" % fileRelativePath)
# print(" %s" % fileRelativePath)
zipFp.write(curFilePath, arcname=fileRelativePath)
print("Completed zip file %s" % outputZipFile)
toZipFullPath = "/Users/crifan/dev/dev_root/iosReverse/WhatsApp/ipa/forRepackIpa_20231128"
outputZipFile = "/Users/crifan/dev/dev_root/iosReverse/WhatsApp/ipa/WhatsApp_v23.24.0_20231128.ipa"
zipFolder(toZipFullPath, outputZipFile)
输出:
Zip for foler /Users/crifan/dev/dev_root/iosReverse/WhatsApp/ipa/forRepackIpa_20231128
Completed zip file /Users/crifan/dev/dev_root/iosReverse/WhatsApp/ipa/WhatsApp_v23.20.79_idaAllSymbols_20231128.ipa
shutil
中的make_archive
(如果您想要递归压缩单个目录)。不要使用被接受的答案中提出的解决方案。 - malanashutil.make_archive
有关的注意事项 - 它似乎不遵循符号链接。 - LRE