如何检查它是否是python中存档的文件或文件夹?

时间:2016-02-29 00:19:49

标签: python zip archive

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

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

4 个答案:

答案 0 :(得分:5)

您已声明需要支持“tar,bz2,zip或tar.gz”。 Python的tarfile模块将自动处理gz和bz2压缩的tar文件,因此实际上只需要支持两种类型的存档: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 is a directory
x/4 is a unknown
x/3 is a directory
x/3/4 is a directory
x/3/4/zzz is a file
x/2 is a directory
x/2/aa is a file
x/1 is a directory
x/1/abc is a file
x/1/ab is a file
x/1/a is a file

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

使用zipfile没有简单的方法来区分符号链接(或其他文件类型)与目录或普通文件。这些信息存在于ZipInfo.external_attr属性中,但要将其恢复原状会很麻烦:

import stat

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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

您可以使用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

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

答案 3 :(得分:0)

你可以使用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