os.listdir模拟压缩目录

时间:2016-06-20 14:24:29

标签: python python-2.7 python-3.x zipfile

我的目标是列出zip存档中某个 sub 目录中包含的所有文件。

os.listdir(target_dir)引发FileNotFoundErrorzfile.namelist()只列出所有目录中的所有文件。

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

您可以使用提供的zip_listdir函数,该函数有点快,但应始终在Unix克隆中使用。

class MockZipFile(object):
    fake_file_names = [
        "string.pyc",  # Top level name
        "test/__init__.pyc",  # Package directory
        "test/test_support.pyc",  # Module test.test_support
        "test/bogus/__init__.pyc",  # Subpackage directory
        "test/bogus/myfile.pyc"  # Submodule test.bogus.myfile
    ]

    def namelist(self):
        return self.fake_file_names


def zip_listdir(zip_file, target_dir):

    file_names = zip_file.namelist()

    if not target_dir.endswith("/"):
        target_dir += "/"

    if target_dir == "/":
        target_dir = ""

    result = [ file_name
               for file_name in file_names
               if file_name.startswith(target_dir) and
                  not "/" in file_name[len(target_dir):]
               ]

    return result

mockZipfile = MockZipFile()
print zip_listdir(zip_file=mockZipfile, target_dir="test")
print zip_listdir(zip_file=mockZipfile, target_dir="test/bogus")
print zip_listdir(zip_file=mockZipfile, target_dir="test/")
print zip_listdir(zip_file=mockZipfile, target_dir="/")
print zip_listdir(zip_file=mockZipfile, target_dir="")
print zip_listdir(zip_file=mockZipfile, target_dir="/asd")

请注意我创建了一个MockZipFile类,并将其用作zip_listdir函数的输入,但正确的zipfile对象应该完全相同。

答案 1 :(得分:1)

尝试以下方法:

files = list(filter(lambda f: f.startswith("subdir"), zfile.namelist()))

print(files)

说明:filter过滤zfile.namelist()lambda提供的列表,检查文件名是否以“subdir”开头。

filter函数不返回列表,而是返回过滤器对象(生成器),因此我们需要将其转换为列表。

您还可以使用以下相同但使用列表理解的行:

files = [f for f in zfile.namelist() if f.startswith("subdir")]

编辑:正如advance512所指出的那样:“此解决方案的问题在于它还将返回您正在检查的子目录中的子目录中的文件。”:

files = [f for f in zfile.namelist() if f.startswith("subdir") and f.count("/") == 1]

这不会返回子子目录中的任何文件。