【问题标题】:How to check if it is a file or folder for an archive in python?如何检查它是否是python中存档的文件或文件夹?
【发布时间】:2016-06-11 22:22:55
【问题描述】:

我有一个存档,我不想提取它,但要检查它的每个内容是文件还是目录。

os.path.isdir 和 os.path.isfile 不起作用,因为我正在处理存档。存档可以是 tar、bz2、zip 或 tar.gz 中的任何一个(所以我不能使用他们特定的库)。另外,代码应该可以在任何平台上运行,比如 linux 或 windows。有人可以帮我怎么做吗?

【问题讨论】:

  • 不,因为存档可以是任何类型(存档的类型很多)
  • 这在理论上应该可以通过解析文件来实现……但是为什么不能解压呢?
  • 我必须上传存档并解压缩,但在上传之前,我必须进行一些检查。
  • 也许其中之一可以帮助您入门:
  • 存档的类型太多,无法为每种类型编写单独的代码

标签: python zip archive


【解决方案1】:

您已声明需要支持“tar、bz2、zip 或 tar.gz”。 Python 的 tarfile 模块会自动处理 gz 和 bz2 压缩的 tar 文件,因此您实际上只需要支持 2 种类型的存档:tar 和 zip。 (bz2 本身不是存档格式,它只是压缩)。

您可以使用tarfile.is_tarfile() 确定给定文件是否为tar 文件。这也适用于使用 gzip 或 bzip2 压缩的 tar 文件。在 tar 文件中,您可以确定文件是使用 TarInfo.isdir() 的目录还是使用 TarInfo.isfile() 的文件。

同样,您可以使用zipfile.is_zipfile() 确定文件是否为 zip 文件。 zipfile 没有办法区分目录和普通文件,但以/ 结尾的文件是目录。

所以,给定一个文件名,你可以这样做:

import zipfile
import tarfile

filename = 'test.tgz'

if tarfile.is_tarfile(filename):
    f = tarfile.open(filename)
    for info in f:
        if info.isdir():
            file_type = 'directory'
        elif info.isfile():
            file_type = 'file'
        else:
            file_type = 'unknown'
        print('{} is a {}'.format(info.name, file_type))

elif zipfile.is_zipfile(filename):
    f = zipfile.ZipFile(filename)
    for name in f.namelist():
         print('{} is a {}'.format(name, 'directory' if name.endswith('/') else 'file'))

else:
    print('{} is not an accepted archive file'.format(filename))

在具有这种结构的 tar 文件上运行时:

(py2)[mhawke@localhost tmp]$ tar tvfz /tmp/test.tgz drwxrwxr-x mhawke/mhawke 0 2016-02-29 12:38 x/ lrwxrwxrwx mhawke/mhawke 0 2016-02-29 12:38 x/4 -> 3 drwxrwxr-x mhawke/mhawke 0 2016-02-28 21:14 x/3/ drwxrwxr-x mhawke/mhawke 0 2016-02-28 21:14 x/3/4/ -rw-rw-r-- mhawke/mhawke 0 2016-02-28 21:14 x/3/4/zzz drwxrwxr-x mhawke/mhawke 0 2016-02-28 21:13 x/2/ -rw-rw-r-- mhawke/mhawke 0 2016-02-28 21:13 x/2/aa drwxrwxr-x mhawke/mhawke 0 2016-02-28 21:13 x/1/ -rw-rw-r-- mhawke/mhawke 0 2016-02-28 21:13 x/1/abc -rw-rw-r-- mhawke/mhawke 0 2016-02-28 21:13 x/1/ab -rw-rw-r-- mhawke/mhawke 0 2016-02-28 21:13 x/1/a

输出是:

x 是一个目录 x/4 是未知数 x/3 是一个目录 x/3/4 是一个目录 x/3/4/zzz 是一个文件 x/2 是一个目录 x/2/aa 是一个文件 x/1 是一个目录 x/1/abc 是一个文件 x/1/ab 是一个文件 x/1/a 是一个文件

注意x/4 是“未知的”,因为它是一个符号链接。

zipfile 没有简单的方法可以将符号链接(或其他文件类型)与目录或普通文件区分开来。信息在ZipInfo.external_attr 属性中,但是把它拿回来很麻烦:

import stat

linked_file = f.filelist[1]
is_symlink = stat.S_ISLNK(linked_file.external_attr >> 16L)

【讨论】:

    【解决方案2】:

    我得到了答案。就是我们可以使用两个命令:archive.getall_members() 和archive.getfile_members()。

    我们遍历它们中的每一个并将文件/文件夹名称存储在两个数组 a1(包含文件/文件夹名称)和 a2(仅包含文件名称)中。如果两个数组都包含该元素,则它是一个文件,否则它是一个文件夹。

    【讨论】:

    • 什么是archive.getall_members()。这是什么包?
    • 是utils.archives
    • utils 包是什么?从何而来?姜戈?
    • 是的,它来自 django。
    • 我在任何版本的 Django 中都找不到这些功能。您使用的是哪个版本?您还应该知道,这些函数,与来自 django.utils 的其他函数一样,可能会在 Django 的未来版本中消失。
    【解决方案3】:

    您可以使用string.endswith(string) 方法检查它是否具有正确的文件扩展名:

    filenames = ['code.tar.gz', 'code2.bz2', 'code3.zip']
    fileexts = ['.tar.gz', '.bz2', '.zip']
    
    def check_extension():
        for name in filenames:
            for ext in fileexts:
                if name.endswith(ext):
                    print ('The file: ', name, ' has the extension: ', ext)
    
    
    check_extension()
    

    哪个输出:

    The file:  code.tar.gz  has the extension:  .tar.gz
    The file:  code2.bz2  has the extension:  .bz2
    The file:  code3.zip  has the extension:  .zip
    

    您必须为要检查的每种存档文件类型创建文件扩展名列表,并且需要将文件名加载到可以轻松执行检查的列表中,但我认为这将是解决您的问题的一种相当有效的方法。

    【讨论】:

    • 我正在检查存档内容的文件类型,而不是存档本身的文件类型。请阅读我的解决方案。它有效。
    • 抱歉我的错误,我对你问题的解释是错误的。
    【解决方案4】:

    您可以使用 python-magic 模块并解析它的输出。

    [root@jasonralph ~]# yum install python-pip
    
    [root@jasonralph ~]# pip install python-magic
    
    [root@jasonralph ~]# cat py_file_check.py
    #!/usr/bin/python
    
    import magic
    print magic.from_file('jason_ralph_org_20160215.tar.gz')
    
    [root@jasonralph ~]# file jason_ralph_org_20160215.tar.gz
    jason_ralph_org_20160215.tar.gz: gzip compressed data, from Unix, last   modified: Mon Feb 29 01:33:25 2016
    
    > [root@jasonralph ~]# python py_file_check.py
    >         gzip compressed data, from Unix, last modified: Mon Feb 29 01:33:25 2016
    

    【讨论】:

    • 我正在检查存档内容的文件类型,而不是存档本身的文件类型。请阅读我的解决方案。它有效
    猜你喜欢
    • 2010-12-10
    • 2018-12-26
    • 1970-01-01
    • 2013-06-08
    • 1970-01-01
    • 2011-11-15
    • 2023-03-12
    • 2012-02-05
    • 1970-01-01
    相关资源
    最近更新 更多