使用 Python 和 ftplib 检查 FTP 服务器上的对象是文件还是目录

Checking if object on FTP server is file or directory using Python and ftplib

使用 Python 和 ftplib,我正在编写一个通用函数来检查 FTP 目录中的项目是文件还是目录。由于使用 MLSD 函数可能不一定适用于所有服务器(我的一个用例没有提供它)我已经采用这种有效但粗略的方式来确定它,通过尝试将目录更改为对象以及对象是否是一个文件,引发异常并相应地设置文件类型。

file_type = ''
try:
    ftp.cwd(item_name)
    file_type = 'dir'
    ftp.cwd(cur_path)
except ftplib.error_perm:
    file_type = 'file'

我已经在 Internet 和图书馆文档中搜索了其他方法,但找不到适用于大多数情况的方法。

例如,使用 dir 函数,我可以检查第一个字符是否为 'd',这可能会确定它,但是进一步阅读表明并非所有输出都具有相同的格式。

我在这个方法中看到的最大缺陷是如果我没有权限将目录更改到指定的文件夹;因此它将被视为一个文件。

有没有我遗漏的东西或更简洁的方法?

没有更好的方法(通常使用 FTP 协议,而不仅仅是使用 ftplib)。

MLST/MLSD是唯一正确可靠的方法。

如果您无法使用 MLST/MLSD,尝试 CWD 是下一个最佳选择。

尝试解析 LIST 是一个后备选项。但是您需要知道服务器使用您的程序可以理解的列表格式。

这是我在 FTP 的 os.walk 版本中为 FTP 服务器使用的一个函数。这里是 github link 如果你想看到完整的代码 https://github.com/Kasramvd/FTPwalk:

def listdir(self, connection, _path):
    file_list, dirs, nondirs = [], [], []
    try:
        connection.cwd(_path)
    except:
        return [], []

    connection.retrlines('LIST', lambda x: file_list.append(x.split()))
    for info in file_list:
        ls_type, name = info[0], info[-1]
        if ls_type.startswith('d'):
            dirs.append(name)
        else:
            nondirs.append(name)
    return dirs, nondirs

解释:

在这里,您所需要做的就是遍历目标目录中的文件和目录并选择目录。但是因为你不能像你在 OS 中使用的那样那样做,你需要使用 ftplib.FTP.retrlines() 函数来检索 ASCII 传输模式下的文件或目录列表,然后你可以通过解析这些行来分离目录.