You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Paramiko的SFTPClient判断远程路径是否为目录的问题

在Paramiko 3.4.0中判断远程SFTP路径是否为目录的正确方法

Paramiko的SFTPAttributes对象既没有st_isdir()方法,也没有直接的isdir()方法,你遇到的AttributeError是因为调用了不存在的属性。正确的判断方式是通过st_mode属性结合文件模式常量进行位运算判断。

基础判断方法

直接通过stat()获取路径属性,然后利用S_IFDIR常量判断是否为目录:

import paramiko

def is_remote_dir(sftp, remote_path):
    try:
        attrs = sftp.stat(remote_path)
        # 位运算判断是否为目录类型
        return (attrs.st_mode & paramiko.sftp.S_IFDIR) != 0
    except FileNotFoundError:
        # 路径不存在时返回False,可根据需求调整逻辑
        return False

也可以使用Python标准库os的stat常量,效果一致:

import os
import paramiko

def is_remote_dir(sftp, remote_path):
    try:
        attrs = sftp.stat(remote_path)
        return (attrs.st_mode & os.stat.S_IFDIR) != 0
    except FileNotFoundError:
        return False

处理符号链接的情况

如果需要区分符号链接本身和其指向的目标,用lstat()代替stat()(stat()会自动跟随符号链接,返回目标的属性):

import paramiko

def is_remote_dir(sftp, remote_path):
    try:
        attrs = sftp.lstat(remote_path)
        # 先判断是否为符号链接
        if (attrs.st_mode & paramiko.sftp.S_IFLNK) != 0:
            # 读取链接目标,注意处理相对路径
            target_path = sftp.readlink(remote_path)
            # 递归判断目标是否为目录
            return is_remote_dir(sftp, target_path)
        return (attrs.st_mode & paramiko.sftp.S_IFDIR) != 0
    except FileNotFoundError:
        return False

递归下载时的使用示例

在遍历远程目录时,用上述函数判断每个条目类型,实现递归下载:

import os
import paramiko

def recursive_download(sftp, remote_dir, local_dir):
    os.makedirs(local_dir, exist_ok=True)
    for item in sftp.listdir(remote_dir):
        remote_item_path = f"{remote_dir}/{item}"
        local_item_path = f"{local_dir}/{item}"
        if is_remote_dir(sftp, remote_item_path):
            recursive_download(sftp, remote_item_path, local_item_path)
        else:
            sftp.get(remote_item_path, local_item_path)

内容的提问来源于stack exchange,提问作者Gabi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 04:35:03