使用Python解压文件并返回所有创建的目录
我想知道怎么用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
里创建的目录呢?谢谢。
补充:对我来说,最合理的解决方案是只获取压缩文件中的顶层目录,然后递归地遍历这些目录,这样可以确保我能获取到压缩文件生成的所有文件。这可能吗?因为系统特定的行为使得使用namelist几乎不可靠。
4 个回答
等它完成后,再查看目录的内容 - 这里有一个不错的例子。
ZipFile.namelist
这个方法会返回一个压缩文件里所有项目的名字列表。不过,这些名字会包含完整的文件名和它们的目录路径。(一个压缩文件只能包含文件,而不能直接包含目录,所以目录是通过文件名来隐含表示的。)如果你想知道创建了哪些目录,就需要列出每个文件隐含创建的目录。
下面的 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))
你可以使用 namelist()
方法来读取压缩文件的内容。目录的后面会有一个路径分隔符:
>>> import zipfile
>>> zip = zipfile.ZipFile('test.zip')
>>> zip.namelist()
['dir2/', 'file1']
你可以在提取内容之前或之后进行这个操作。
根据你的操作环境,namelist()
的结果可能只显示压缩文件的顶层路径(比如在 Linux 上的 Python),或者可能显示压缩文件的全部内容(比如在 Windows 上的 IronPython)。
namelist()
会返回压缩文件内容的完整列表,目录会用一个路径分隔符来标记。例如,假设有以下文件结构的压缩文件:
./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' ]