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

Python使用pysftp批量上传文件到SFTP服务器报错排查

问题根因
  • 核心错误是路径拼接缺失:os.listdir('C:/Test/')仅返回目录下的文件名,不包含C:/Test/前缀,调用conn.put(file)时,程序会在Python脚本的当前运行目录下找对应的文件,根本读不到C:/Test/下的真实文件,直接触发上传失败。你单文件上传时如果写了完整文件路径可以正常运行,就是这个原因。
  • 连接管理逻辑有缺陷:如果SFTP连接建立失败,conn变量根本不会被初始化,后续直接调用conn.cd('/')会直接抛变量不存在的错误;就算连接建立成功,上传过程中触发异常后连接会非正常断开,pysftp在自动销毁连接对象时就会抛出你看到的'NoneType' object has no attribute 'time'异常,这个是连带报错,不是问题根源。
  • 异常捕获逻辑太粗糙:所有异常都只打印固定提示,吞掉了具体错误信息,根本没法定位真实失败原因;同时没有过滤本地目录下的子文件夹,遍历到文件夹时调用put接口也会触发上传失败。
修复后代码
import pysftp
import os

# 替换为实际的SFTP配置信息
host = "你的SFTP服务器地址"
port = 22
username = "你的登录用户名"
password = "你的登录密码"
local_dir = "C:/Test/"
remote_dir = "/"

cnopts = pysftp.CnOpts()
cnopts.hostkeys = None

# 用上下文管理器自动维护连接生命周期,异常时也能正常关闭连接
with pysftp.Connection(
    host=host,
    port=port,
    username=username,
    password=password,
    cnopts=cnopts
) as conn:
    print("SFTP连接建立成功")
    conn.cd(remote_dir)
    for filename in os.listdir(local_dir):
        # 拼接本地文件的完整绝对路径,解决找不到文件的核心问题
        local_file = os.path.join(local_dir, filename)
        # 跳过子目录等非文件项,避免上传目录触发报错
        if not os.path.isfile(local_file):
            print(f"跳过非文件项:{filename}")
            continue
        try:
            conn.put(local_file)
            print(f"上传成功:{filename}")
        except Exception as e:
            print(f"上传失败:{filename},错误详情:{str(e)}")
关键修复点
  • 补全本地文件路径:通过os.path.join()拼接目录路径和文件名,保证程序能正确读到本地待上传文件
  • 用with语句管理SFTP连接:无论代码运行正常还是抛出异常,都会自动正常关闭连接,彻底解决连接析构时抛出的NoneType连带报错
  • 增加文件类型校验:遍历过程中跳过子文件夹、快捷方式等非文件项,避免无效上传请求
  • 细化异常输出:捕获上传异常时打印具体错误信息,方便快速定位是文件占用、权限不足还是路径错误问题
  • 把连接操作纳入上下文管理范围:避免连接建立失败后调用不存在的连接对象触发低级错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 03:12:23