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

新手上路,请多包涵

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

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

原文由 Sam 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 270
1 个回答

您已经声明您需要支持“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 姆霍克/姆霍克 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)

原文由 mhawke 发布,翻译遵循 CC BY-SA 3.0 许可协议

推荐问题