os.listdir 模拟压缩目录

Posted

技术标签:

【中文标题】os.listdir 模拟压缩目录【英文标题】:os.listdir analog for a zipped directory 【发布时间】:2016-06-20 14:24:28 【问题描述】:

我的目标是列出某个 sub 压缩包内的某个目录中包含的所有文件。

os.listdir(target_dir) 引发FileNotFoundError,而zfile.namelist() 仅列出所有目录中的所有文件。

有什么想法吗?

【问题讨论】:

【参考方案1】:

尝试以下方法:

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

print(files)

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

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]

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

【讨论】:

这个解决方案的问题是它还会返回您正在检查的子目录内的子目录中的文件。如果这是您正在寻找的,那么这是一个很好的解决方案(我通常也更喜欢 lambda 和理解,但您要求的是一个函数)。 @advance512 谢谢,我没有考虑过。我更新了我的答案。 或者您可以使用正则表达式来获取特定子目录的所有文件(≠子目录):files = [f for f in zipfile.namelist() if re.compile("^(" + re.escape("subdir") + r"\/[^\/]*?)$").match(f)]。但在这种情况下,您必须导入并使用 re 模块。因此,我更喜欢@SimonKirsten 原始答案。 另外,在@Darius 代码示例中,您会为每个文件名编译一次正则表达式...性能不佳。如果有的话,在理解之外编译正则表达式。在这种情况下,正则表达式似乎有点矫枉过正。【参考方案2】:

您可以使用提供的 zip_listdir 函数,该函数有点快-n-dirty,但应该始终可以在 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 对象应该完全相同。

【讨论】:

以上是关于os.listdir 模拟压缩目录的主要内容,如果未能解决你的问题,请参考以下文章

python使用os.listdir和os.walk获得文件的路径

os模块

os.listdir(path)

Python3基础 os listdir curdir查看当前工作目录的所有文件的名字

Python3.x:os.listdir和os.walk(获取路径方法)的区别

关于搜索全部文件和修改文件名的方法os.walk() 和os.listdir