如何检查它是否是python中存档的文件或文件夹? [英] How to check if it is a file or folder for an archive in python?

查看:25
本文介绍了如何检查它是否是python中存档的文件或文件夹?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个存档,我不想提取它,而是检查其中的每个内容是文件还是目录.

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

解决方案

您已经声明您需要支持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 没有办法区分目录和普通文件,但以 / 结尾的文件就是目录.

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

导入压缩文件导入 tarfile文件名 = 'test.tgz'如果 tarfile.is_tarfile(文件名):f = tarfile.open(文件名)有关 f 中的信息:如果 info.isdir():文件类型 = '目录'elif info.isfile():文件类型 = '文件'别的:文件类型 = '未知'print('{} 是一个 {}'.format(info.name, file_type))elif zipfile.is_zipfile(文件名):f = zipfile.ZipFile(文件名)对于 f.namelist() 中的名称:print('{} 是一个 {}'.format(name, 'directory' if name.endswith('/') else 'file'))别的:print('{} 不是可接受的存档文件'.format(filename))

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

<前>(py2)[mhawke@localhost tmp]$ tar tvfz/tmp/test.tgzdrwxrwxr-x mhawke/mhawke 0 2016-02-29 12:38 x/lrwxrwxrwx mhawke/mhawke 0 2016-02-29 12:38 x/4 -> 3drwxrwxr-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/zzzdrwxrwxr-x mhawke/mhawke 0 2016-02-28 21:13 x/2/-rw-rw-r-- mhawke/mhawke 0 2016-02-28 21:13 x/2/aadrwxrwxr-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 属性中,但将其取回很麻烦:

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

I have an archive which I do not want to extract but check for each of its contents whether it is a file or a directory.

os.path.isdir and os.path.isfile do not work because I am working on archive. The archive can be anyone of tar,bz2,zip or tar.gz(so I cannot use their specific libraries). Plus, the code should work on any platform like linux or windows. Can anybody help me how to do it?

解决方案

You've stated that you need to support "tar, bz2, zip or tar.gz". Python's tarfile module will automatically handle gz and bz2 compressed tar files, so there is really only 2 types of archive that you need to support: tar and zip. (bz2 by itself is not an archive format, it's just compression).

You can determine whether a given file is a tar file with tarfile.is_tarfile(). This will also work on tar files compressed with gzip or bzip2 compression. Within a tar file you can determine whether a file is a directory using TarInfo.isdir() or a file with TarInfo.isfile().

Similarly you can determine whether a file is a zip file using zipfile.is_zipfile(). With zipfile there is no method to distinguish directories from normal file, but files that end with / are directories.

So, given a file name, you can do this:

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))

When run on a tar file with this structure:

(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

The output is:

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

Notice that x/4 is "unknown" because it is a symbolic link.

There is no easy way, with zipfile, to distinguish a symlink (or other file types) from a directory or normal file. The information is there in the ZipInfo.external_attr attribute, but it's messy to get it back out:

import stat

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

这篇关于如何检查它是否是python中存档的文件或文件夹?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆