使用Python检查zip文件中是否存在目录

问题描述 投票:0回答:5

最初我想使用

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

python unzip
5个回答
14
投票

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

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())

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

执行结果:

$ 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

8
投票

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

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

z = zipfile.ZipFile("myfile.zip")
if dir in z.namelist():
    print "Found %s!" % dir

2
投票

对于Python(> = 3.6):

这就是

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

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

它只是检查文件名是否以斜杠结尾

/
,无法判断这在某些特定情况下是否能正常工作(所以在我看来,它实施得很糟糕)。

对于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

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 测试并正常运行。


0
投票

此处未列出,但这可以通过字典查找来完成。

import os, zipfile

def zip_contains_dir(zip_handle, path):
    # Ensure trailing slash.
    path = path.rstrip("/") + "/"
    return path in zip_handle.NameToInfo


with zipfile.ZipFile("myfile.zip") as zip_handle:
    print(zip_contains_dir(zip_handle, "some/dir"))

© www.soinside.com 2019 - 2024. All rights reserved.