14

最初我正在考虑使用os.path.isdir,但我认为这不适用于 zip 文件。有没有办法查看 zip 文件并验证该目录是否存在?我想尽可能避免使用unzip -l "$@",但如果这是唯一的解决方案,那么我想我别无选择。

4

4 回答 4

13

只需检查文件名末尾带有“/”的文件名。

import zipfile

def isdir(z, name):
    return any(x.startswith("%s/" % name.rstrip("/")) for x in z.namelist())

f = zipfile.ZipFile("sample.zip", "r")
print isdir(f, "a")
print isdir(f, "a/b")
print isdir(f, "a/X")

你用这条线

any(x.startswith("%s/" % name.rstrip("/")) for x in z.namelist())

因为存档可能不包含明确的目录;只是带有目录名称的路径。

执行结果:

$ mkdir -p a/b/c/d
$ touch a/X
$ zip -r sample.zip a
adding: a/ (stored 0%)
adding: a/X (stored 0%)
adding: a/b/ (stored 0%)
adding: a/b/c/ (stored 0%)
adding: a/b/c/d/ (stored 0%)

$ python z.py
True
True
False
于 2012-07-23T17:38:17.327 回答
6

您可以使用ZipFile.namelist()检查目录。

import os, zipfile
dir = "some/directory/"

z = zipfile.ZipFile("myfile.zip")
if dir in z.namelist():
    print "Found %s!" % dir
于 2012-07-23T17:32:11.793 回答
2

对于python(> = 3.6):

这是is_dir()在python源代码中实现的方式:

def is_dir(self):
    """Return True if this archive member is a directory."""
    return self.filename[-1] == '/'

它只是检查文件名是否以斜杠结尾/,无法判断这在某些情况下是否能正常工作(因此 IMO 实施得很糟糕)。

对于python(<3.6):

print(zipinfo)将显示filemode但没有提供相应的属性或字段,我深入研究 zipfile 模块源代码并找到它是如何实现的。(见def __repr__(self): https://github.com/python/cpython/blob/3.6/Lib/zipfile.py

可能是个坏主意,但它会起作用:

如果您想要简单易行的东西,这在大多数情况下都可以使用,但它可能会失败,因为在某些情况下不会打印此字段。

def is_dir(zipinfo):
    return "filemode='d" in zipinfo.__repr__()

最后:

我的解决方案是手动检查文件模式并确定引用的文件是否实际上是受https://github.com/python/cpython/blob/3.6/Lib/zipfile.py第 391 行启发的目录。

def is_dir(fileinfo):
    hi = fileinfo.external_attr >> 16
    return (hi & 0x4000) > 0
于 2018-11-14T03:28:57.383 回答
0

您可以使用内置库 ZipFile 完成此操作。

import zipfile
z = zipfile.ZipFile("file.zip")

if "DirName/" in [member.filename for member in z.infolist()]:
    print("Directory exists in archive")

使用 Python32 测试并运行。

于 2012-07-23T17:46:13.327 回答