如何将带有Python的.zip
文件解压缩到某个目录output_dir
中,并获取解压缩所产生的所有目录的列表?例如,如果我有:
unzip('myzip.zip', 'outdir')
outdir
是一个可能包含其他文件/目录的目录。当我将myzip.zip
解压缩到其中时,我希望unzip
返回由于压缩而在outdir/
中生成的所有目录。到目前为止,这是我的代码:
import zipfile
def unzip(zip_file, outdir):
"""
Unzip a given 'zip_file' into the output directory 'outdir'.
"""
zf = zipfile.ZipFile(zip_file, "r")
zf.extractall(outdir)
如何让unzip
返回它在outdir
中创建的目录?感谢。
编辑:对我来说最有意义的解决方案是只获取zip文件中的顶级目录,然后递归遍历它们,这将保证我获得zip所生成的所有文件。这可能吗?名单的系统特定行为使得几乎不可能依赖
答案 0 :(得分:8)
您可以使用namelist()
方法阅读zip文件的内容。目录将具有尾随路径分隔符:
>>> import zipfile
>>> zip = zipfile.ZipFile('test.zip')
>>> zip.namelist()
['dir2/', 'file1']
提取内容后,您可以在或之前执行此操作。
根据您的操作环境, namelist()
的结果可能仅限于zip存档的顶级路径(例如Linux上的Python),或者可能涵盖存档的全部内容(例如Windows上的IronPython。
namelist()
返回zip存档内容的完整列表,其中目录标有尾随路径分隔符。例如,以下文件结构的zip存档:
./file1
./dir2
./dir2/dir21
./dir3
./dir3/file3
./dir3/dir31
./dir3/dir31/file31
导致zipfile.ZipFile.namelist()
返回以下列表:
[ 'file1',
'dir2/',
'dir2/dir21/',
'dir3/',
'dir3/file3',
'dir3/dir31/',
'dir3/dir31/file31' ]
答案 1 :(得分:1)
ZipFile.namelist
将返回存档中项目名称的列表。但是,这些名称只是文件的全名,包括其目录路径。 (zip文件只能包含文件,而不能包含目录,因此存档成员名称隐含了目录。)要确定创建的目录,需要每个文件隐式创建的每个目录的列表。
下面的dirs_in_zip()
函数会执行此操作并将所有目录名称收集到一个集合中。
import zipfile
import os
def parent_dirs(pathname, subdirs=None):
"""Return a set of all individual directories contained in a pathname
For example, if 'a/b/c.ext' is the path to the file 'c.ext':
a/b/c.ext -> set(['a','a/b'])
"""
if subdirs is None:
subdirs = set()
parent = os.path.dirname(pathname)
if parent:
subdirs.add(parent)
parent_dirs(parent, subdirs)
return subdirs
def dirs_in_zip(zf):
"""Return a list of directories that would be created by the ZipFile zf"""
alldirs = set()
for fn in zf.namelist():
alldirs.update(parent_dirs(fn))
return alldirs
zf = zipfile.ZipFile(zipfilename, 'r')
print(dirs_in_zip(zf))
答案 2 :(得分:0)
让它完成,然后阅读目录的内容 - 这是good example。
答案 3 :(得分:0)
假设没有其他人同时编写目标目录,请在解压缩之前递归遍历目录,然后再比较结果。