如何创建目录的 zip 存档?
Posted
技术标签:
【中文标题】如何创建目录的 zip 存档?【英文标题】:How to create a zip archive of a directory? 【发布时间】:2009-12-06 11:12:53 【问题描述】:如何在 Python 中创建目录结构的 zip 存档?
【问题讨论】:
不要使用已接受答案中建议的解决方案,而是使用shutil
中的make_archive
(如果您想递归压缩单个目录)。
是的,同意@malana - Martha Yi 似乎未注册 - 那么现在有办法通过社区流程更改接受的答案吗?
一个警告shutil.make_archive
- 它似乎没有遵循符号链接
【参考方案1】:
最简单的方法是使用shutil.make_archive
。它支持 zip 和 tar 格式。
import shutil
shutil.make_archive(output_filename, 'zip', dir_name)
如果您需要做一些比压缩整个目录更复杂的事情(例如跳过某些文件),那么您需要像其他人建议的那样深入研究 zipfile
模块。
【讨论】:
shutil
是标准 python 库的一部分。这应该是最佳答案
这是这里最简洁的答案,并且还具有将所有子目录和文件直接添加到存档的优点,而不是将所有内容都包含在***文件夹中(这会导致冗余级别)解压时的文件夹结构)。
@cmcginty 您能否更具体地说明它的哪些方面不是线程安全的?调用这个时运行多个线程会导致解释器崩溃吗?
请注意,在 Python 3.4 之前,shutil.make_archive 不支持 ZIP64,并且无法创建大于 2GB 的 ZIP 文件。
@Teekin 否。如果您查看错误报告 (bugs.python.org/issue30511),您会看到 shutil.make_archive
使用 os.chdir()
。从我读到的关于os.chdir()
的内容来看,它在全球范围内运作。【参考方案2】:
正如其他人指出的那样,您应该使用zipfile。该文档告诉您哪些功能可用,但并没有真正解释如何使用它们来压缩整个目录。我认为用一些示例代码来解释是最容易的:
import os
import zipfile
def zipdir(path, ziph):
# ziph is zipfile handle
for root, dirs, files in os.walk(path):
for file in files:
ziph.write(os.path.join(root, file),
os.path.relpath(os.path.join(root, file),
os.path.join(path, '..')))
with zipfile.ZipFile('Python.zip', 'w', zipfile.ZIP_DEFLATED) as zipf:
zipdir('tmp/', zipf)
【讨论】:
我会在 write 调用中添加第二个参数,传递os.path.relpath(os.path.join(root, file), os.path.join(path, '..'))
。这样您就可以从任何工作目录中压缩目录,而无需在存档中获取完整的绝对路径。
当我尝试压缩一个文件夹并将生成的 zip 输出到同一个文件夹时,会发生一个有趣的递归。 :-)
shutil
只需一行代码即可轻松完成。请检查下面的答案..
你可能会更感兴趣 ziph.write(os.path.join(path,file), arcname=file) 这样存档中的文件名与硬盘驱动器无关跨度>
啊,我错过了.close()
电话!【参考方案3】:
要将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()
【讨论】:
对我来说,这段代码抛出错误 TypeError: invalid file:with
而不是最后自己打电话给close()
吗?
示例:` with zipfile.ZipFile("myzipfile.zip", "w") as zf: pass `
这会在生成的 zip 文件中重建“mydirectory”的完整路径。即仅当“mydirectory”位于文件系统的根目录中时才能按需要工作【参考方案4】:
如何在 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/*
和
$ python zipname
将运行包。 (请注意,您不能将子包作为压缩存档的入口点运行。)
压缩 Python 应用程序:
如果您有 python3.5+,并且特别想压缩 Python 包,请使用zipapp:
$ python -m zipapp myapp
$ python myapp.pyz
【讨论】:
【参考方案5】:此函数将递归压缩目录树,压缩文件,并在存档中记录正确的相对文件名。归档条目与zip -r output.zip source_dir
生成的相同。
import os
import zipfile
def make_zipfile(output_filename, source_dir):
relroot = os.path.abspath(os.path.join(source_dir, os.pardir))
with zipfile.ZipFile(output_filename, "w", zipfile.ZIP_DEFLATED) as zip:
for root, dirs, files in os.walk(source_dir):
# add directory (needed for empty dirs)
zip.write(root, os.path.relpath(root, relroot))
for file in files:
filename = os.path.join(root, file)
if os.path.isfile(filename): # regular files only
arcname = os.path.join(os.path.relpath(root, relroot), file)
zip.write(filename, arcname)
【讨论】:
甜蜜,我想知道zipfile
是否可以在with
语句中使用。感谢您指出它可以。【参考方案6】:
使用shutil,它是python标准库集的一部分。 使用shutil非常简单(见下面的代码):
第一个参数:生成的 zip/tar 文件的文件名, 第二个参数:zip/tar, 第三个参数:目录名称代码:
import shutil
shutil.make_archive('/home/user/Desktop/Filename','zip','/home/username/Desktop/Directory')
【讨论】:
这里所有的 shutil.make_archvie 示例都创建了空的根文件夹,通向您实际要归档的文件夹。我不希望我的存档文件使用“/home/user/Desktop”取消存档,这样每个人都可以看到感兴趣的文件夹最初的位置。我如何压缩“/Directory”并忽略父文件夹的所有痕迹? 这已经说了3次了。这绝对不是最好的答案。【参考方案7】:现代 Python (3.6+) 使用 pathlib
模块进行简洁的类似 OOP 的路径处理,使用 pathlib.Path.rglob()
进行递归通配。据我所知,这相当于 George V. Reilly 的回答:压缩压缩,最顶层元素是目录,保留空目录,使用相对路径。
from pathlib import Path
from zipfile import ZIP_DEFLATED, ZipFile
from os import PathLike
from typing import Union
def zip_dir(zip_name: str, source_dir: Union[str, PathLike]):
src_path = Path(source_dir).expanduser().resolve(strict=True)
with ZipFile(zip_name, 'w', ZIP_DEFLATED) as zf:
for file in src_path.rglob('*'):
zf.write(file, file.relative_to(src_path.parent))
注意:如可选类型提示所示,zip_name
不能是 Path 对象 (would be fixed in 3.6.2+)。
【讨论】:
太棒了!简洁的!现代!【参考方案8】:要对生成的 zip 文件添加压缩,请查看 this link。
你需要改变:
zip = zipfile.ZipFile('Python.zip', 'w')
到
zip = zipfile.ZipFile('Python.zip', 'w', zipfile.ZIP_DEFLATED)
【讨论】:
【参考方案9】:借助 python 3.9、pathlib
和 zipfile
模块,您可以从系统中的任何位置创建 zip 文件。
def zip_dir(dir: Union[Path, str], filename: Union[Path, str]):
"""Zip the provided directory without navigating to that directory using `pathlib` module"""
# Convert to Path object
dir = Path(dir)
with zipfile.ZipFile(filename, "w", zipfile.ZIP_DEFLATED) as zip_file:
for entry in dir.rglob("*"):
zip_file.write(entry, entry.relative_to(dir))
它整洁、有类型,而且代码更少。
【讨论】:
【参考方案10】:我对@987654321@ 做了一些更改。如果您有空目录,下面的函数还将添加空目录。示例应该更清楚地说明添加到 zip 的路径是什么。
#!/usr/bin/env python
import os
import zipfile
def addDirToZip(zipHandle, path, basePath=""):
"""
Adding directory given by \a path to opened zip file \a zipHandle
@param basePath path that will be removed from \a path when adding to archive
Examples:
# add whole "dir" to "test.zip" (when you open "test.zip" you will see only "dir")
zipHandle = zipfile.ZipFile('test.zip', 'w')
addDirToZip(zipHandle, 'dir')
zipHandle.close()
# add contents of "dir" to "test.zip" (when you open "test.zip" you will see only it's contents)
zipHandle = zipfile.ZipFile('test.zip', 'w')
addDirToZip(zipHandle, 'dir', 'dir')
zipHandle.close()
# add contents of "dir/subdir" to "test.zip" (when you open "test.zip" you will see only contents of "subdir")
zipHandle = zipfile.ZipFile('test.zip', 'w')
addDirToZip(zipHandle, 'dir/subdir', 'dir/subdir')
zipHandle.close()
# add whole "dir/subdir" to "test.zip" (when you open "test.zip" you will see only "subdir")
zipHandle = zipfile.ZipFile('test.zip', 'w')
addDirToZip(zipHandle, 'dir/subdir', 'dir')
zipHandle.close()
# add whole "dir/subdir" with full path to "test.zip" (when you open "test.zip" you will see only "dir" and inside it only "subdir")
zipHandle = zipfile.ZipFile('test.zip', 'w')
addDirToZip(zipHandle, 'dir/subdir')
zipHandle.close()
# add whole "dir" and "otherDir" (with full path) to "test.zip" (when you open "test.zip" you will see only "dir" and "otherDir")
zipHandle = zipfile.ZipFile('test.zip', 'w')
addDirToZip(zipHandle, 'dir')
addDirToZip(zipHandle, 'otherDir')
zipHandle.close()
"""
basePath = basePath.rstrip("\\/") + ""
basePath = basePath.rstrip("\\/")
for root, dirs, files in os.walk(path):
# add dir itself (needed for empty dirs
zipHandle.write(os.path.join(root, "."))
# add files
for file in files:
filePath = os.path.join(root, file)
inZipPath = filePath.replace(basePath, "", 1).lstrip("\\/")
#print filePath + " , " + inZipPath
zipHandle.write(filePath, inZipPath)
上面是一个简单的函数,应该适用于简单的情况。您可以在我的 Gist 中找到更优雅的课程: https://gist.github.com/Eccenux/17526123107ca0ac28e6
【讨论】:
使用os.path可以大大简化路径处理。看我的回答。 Bug:zipHandle.write(os.path.join(root, ".")) 没有考虑basePath。 是的,你可能是对的。我后来对此进行了一些改进 ;-) gist.github.com/Eccenux/17526123107ca0ac28e6【参考方案11】:我有另一个可能有帮助的代码示例,使用 python3、pathlib 和 zipfile。 它应该适用于任何操作系统。
from pathlib import Path
import zipfile
from datetime import datetime
DATE_FORMAT = '%y%m%d'
def date_str():
"""returns the today string year, month, day"""
return ''.format(datetime.now().strftime(DATE_FORMAT))
def zip_name(path):
"""returns the zip filename as string"""
cur_dir = Path(path).resolve()
parent_dir = cur_dir.parents[0]
zip_filename = '/_.zip'.format(parent_dir, cur_dir.name, date_str())
p_zip = Path(zip_filename)
n = 1
while p_zip.exists():
zip_filename = ('/__.zip'.format(parent_dir, cur_dir.name,
date_str(), n))
p_zip = Path(zip_filename)
n += 1
return zip_filename
def all_files(path):
"""iterator returns all files and folders from path as absolute path string
"""
for child in Path(path).iterdir():
yield str(child)
if child.is_dir():
for grand_child in all_files(str(child)):
yield str(Path(grand_child))
def zip_dir(path):
"""generate a zip"""
zip_filename = zip_name(path)
zip_file = zipfile.ZipFile(zip_filename, 'w')
print('create:', zip_filename)
for file in all_files(path):
print('adding... ', file)
zip_file.write(file)
zip_file.close()
if __name__ == '__main__':
zip_dir('.')
print('end!')
【讨论】:
【参考方案12】:对于保留要归档的父目录下的文件夹层次结构的简洁方法:
import glob
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
for file globbing。
【讨论】:
【参考方案13】:如果您想要任何通用图形文件管理器的压缩文件夹等功能,您可以使用以下代码,它使用zipfile 模块。使用此代码,您将拥有以路径作为根文件夹的 zip 文件。
import os
import zipfile
def zipdir(path, ziph):
# Iterate all the directories and files
for root, dirs, files in os.walk(path):
# Create a prefix variable with the folder structure inside the path folder.
# So if a file is at the path directory will be at the root directory of the zip file
# so the prefix will be empty. If the file belongs to a containing folder of path folder
# then the prefix will be that folder.
if root.replace(path,'') == '':
prefix = ''
else:
# Keep the folder structure after the path folder, append a '/' at the end
# and remome the first character, if it is a '/' in order to have a path like
# folder1/folder2/file.txt
prefix = root.replace(path, '') + '/'
if (prefix[0] == '/'):
prefix = prefix[1:]
for filename in files:
actual_file_path = root + '/' + filename
zipped_file_path = prefix + filename
zipf.write( actual_file_path, zipped_file_path)
zipf = zipfile.ZipFile('Python.zip', 'w', zipfile.ZIP_DEFLATED)
zipdir('/tmp/justtest/', zipf)
zipf.close()
【讨论】:
【参考方案14】:这里有这么多答案,我希望我可以用我自己的版本做出贡献,该版本基于原始答案(顺便说一下),但具有更图形化的视角,还为每个 zipfile
设置和排序使用上下文os.walk()
,为了有一个有序的输出。
拥有这些文件夹和文件(以及其他文件夹),我想为每个 cap_
文件夹创建一个 .zip
:
$ tree -d
.
├── cap_01
| ├── 0101000001.json
| ├── 0101000002.json
| ├── 0101000003.json
|
├── cap_02
| ├── 0201000001.json
| ├── 0201000002.json
| ├── 0201001003.json
|
├── cap_03
| ├── 0301000001.json
| ├── 0301000002.json
| ├── 0301000003.json
|
├── docs
| ├── map.txt
| ├── main_data.xml
|
├── core_files
├── core_master
├── core_slave
这是我应用的内容,使用 cmets 可以更好地理解该过程。
$ cat zip_cap_dirs.py
""" Zip 'cap_*' directories. """
import os
import zipfile as zf
for root, dirs, files in sorted(os.walk('.')):
if 'cap_' in root:
print(f"Compressing: root")
# Defining .zip name, according to Capítulo.
cap_dir_zip = '.zip'.format(root)
# Opening zipfile context for current root dir.
with zf.ZipFile(cap_dir_zip, 'w', zf.ZIP_DEFLATED) as new_zip:
# Iterating over os.walk list of files for the current root dir.
for f in files:
# Defining relative path to files from current root dir.
f_path = os.path.join(root, f)
# Writing the file on the .zip file of the context
new_zip.write(f_path)
基本上,对于os.walk(path)
的每次迭代,我都会为zipfile
设置打开一个上下文,然后在files
上进行迭代,这是list
来自root
目录的文件的list
,形成每个文件的相对路径基于当前root
目录,附加到正在运行的zipfile
上下文。
输出如下所示:
$ python3 zip_cap_dirs.py
Compressing: ./cap_01
Compressing: ./cap_02
Compressing: ./cap_03
要查看每个.zip
目录的内容,可以使用less
命令:
$ less cap_01.zip
Archive: cap_01.zip
Length Method Size Cmpr Date Time CRC-32 Name
-------- ------ ------- ---- ---------- ----- -------- ----
22017 Defl:N 2471 89% 2019-09-05 08:05 7a3b5ec6 cap_01/0101000001.json
21998 Defl:N 2471 89% 2019-09-05 08:05 155bece7 cap_01/0101000002.json
23236 Defl:N 2573 89% 2019-09-05 08:05 55fced20 cap_01/0101000003.json
-------- ------- --- -------
67251 7515 89% 3 files
【讨论】:
【参考方案15】:您可能想查看zipfile
模块; http://docs.python.org/library/zipfile.html 有文档。
您可能还希望os.walk()
索引目录结构。
【讨论】:
【参考方案16】:以下是 Nux 给出的对我有用的答案的变体:
def WriteDirectoryToZipFile( zipHandle, srcPath, zipLocalPath = "", zipOperation = zipfile.ZIP_DEFLATED ):
basePath = os.path.split( srcPath )[ 0 ]
for root, dirs, files in os.walk( srcPath ):
p = os.path.join( zipLocalPath, root [ ( len( basePath ) + 1 ) : ] )
# add dir
zipHandle.write( root, p, zipOperation )
# add files
for f in files:
filePath = os.path.join( root, f )
fileInZipPath = os.path.join( p, f )
zipHandle.write( filePath, fileInZipPath, zipOperation )
【讨论】:
【参考方案17】:试试下面的。它对我有用。
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()
【讨论】:
【参考方案18】:为了提供更大的灵活性,例如按名称选择目录/文件使用:
import os
import zipfile
def zipall(ob, path, rel=""):
basename = os.path.basename(path)
if os.path.isdir(path):
if rel == "":
rel = basename
ob.write(path, os.path.join(rel))
for root, dirs, files in os.walk(path):
for d in dirs:
zipall(ob, os.path.join(root, d), os.path.join(rel, d))
for f in files:
ob.write(os.path.join(root, f), os.path.join(rel, f))
break
elif os.path.isfile(path):
ob.write(path, os.path.join(rel, basename))
else:
pass
对于文件树:
.
├── dir
│ ├── dir2
│ │ └── file2.txt
│ ├── dir3
│ │ └── file3.txt
│ └── file.txt
├── dir4
│ ├── dir5
│ └── file4.txt
├── listdir.zip
├── main.py
├── root.txt
└── selective.zip
你可以例如只选择dir4
和root.txt
:
cwd = os.getcwd()
files = [os.path.join(cwd, f) for f in ['dir4', 'root.txt']]
with zipfile.ZipFile("selective.zip", "w" ) as myzip:
for f in files:
zipall(myzip, f)
或者只是在脚本调用目录中 listdir
并从那里添加所有内容:
with zipfile.ZipFile("listdir.zip", "w" ) as myzip:
for f in os.listdir():
if f == "listdir.zip":
# Creating a listdir.zip in the same directory
# will include listdir.zip inside itself, beware of this
continue
zipall(myzip, f)
【讨论】:
这个压缩,但不压缩。【参考方案19】:假设您要压缩当前目录中的所有文件夹(子目录)。
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))
【讨论】:
【参考方案20】:压缩文件或树(目录及其子目录)。
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')
【讨论】:
【参考方案21】:使用pathlib.Path
的解决方案,独立于所使用的操作系统:
import zipfile
from pathlib import Path
def zip_dir(path: Path, zip_file_path: Path):
"""Zip all contents of path to zip_file"""
files_to_zip = [
file for file in path.glob('*') if file.is_file()]
with zipfile.ZipFile(
zip_file_path, 'w', zipfile.ZIP_DEFLATED) as zip_f:
for file in files_to_zip:
print(file.name)
zip_f.write(file, file.name)
current_dir = Path.cwd()
zip_dir = current_dir / "test"
tools.zip_dir(
zip_dir, current_dir / 'Zipped_dir.zip')
【讨论】:
【参考方案22】:显而易见的方法是使用shutil,就像第二个最佳答案所说的那样,但是如果您出于某种原因仍然希望使用ZipFile,并且在这样做时遇到了麻烦(例如ERR 13 in Windows 等),您可以使用此修复:
import os
import zipfile
def retrieve_file_paths(dirName):
filePaths = []
for root, directories, files in os.walk(dirName):
for filename in files:
filePath = os.path.join(root, filename)
filePaths.append(filePath)
return filePaths
def main(dir_name, output_filename):
filePaths = retrieve_file_paths(dir_name)
zip_file = zipfile.ZipFile(output_filename+'.zip', 'w')
with zip_file:
for file in filePaths:
zip_file.write(file)
main("my_dir", "my_dir_archived")
这个递归遍历给定文件夹中的每个子文件夹/文件,并将它们写入 zip 文件,而不是尝试直接压缩文件夹。
【讨论】:
【参考方案23】:这是一种现代方法,使用 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))
【讨论】:
【参考方案24】:我通过将 Mark Byers 的解决方案与 Reimund 和 Morten Zilmer 的 cmets(相对路径并包括空目录)合并来准备一个函数。作为最佳实践,with
用于 ZipFile 的文件构造。
该函数还准备了一个带有压缩目录名称和“.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)))
【讨论】:
【参考方案25】:# 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))
【讨论】:
【参考方案26】:好吧,在阅读了建议之后,我想出了一种非常相似的方法,它可以在 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" )
【讨论】:
【参考方案27】:创建 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()
【讨论】:
请举例说明,以便我更正我的答案 然而,zipfile“目前无法创建加密文件”(来自docs.python.org/3.9/library/zipfile.html)以上是关于如何创建目录的 zip 存档?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Python 创建文件路径的 zip 文件,包括空目录?