pysftp调用conn.put报IOError无此文件但目标端可见完整文件如何解决
可能的原因
- 批量传输时第二个待传输文件的本地路径无效:Errno 2本质是系统找不到对应文件,
conn.put()的第一个参数fileToPush为本地文件路径,如果你是循环批量传输两个文件,第一个文件的本地/远端路径均合法,所以传输成功,第二个文件的本地路径拼写错误、文件被提前删除、或者程序没有读权限,就会触发该异常,直接进入你写的全局异常捕获分支输出报错,看起来就是传成了一个还是抛错。 - 第二个文件的远端父目录不存在:如果
pushedFile配置了多级目录(例如/app/upload/2024/test.txt),但远端对应路径的父目录/app/upload/2024没有提前创建,多数sftp客户端的put方法不会自动创建父目录,也会抛出「No such file」错误。你手动ls查到的是第一个传输成功的文件的目录,不代表第二个文件的远端路径父目录存在。 - sftp客户端库的原子上传逻辑冲突:如果你使用的是paramiko、fabric等封装的sftp连接,这类库默认会先把文件传输为远端的临时文件,传输完成后再重命名为目标文件名。如果远端服务器对临时文件后缀有限制、或者目录有自动清理规则,重命名时找不到临时文件,就会出现文件实际已经传输完成(临时文件改名前已经把内容写完,被规则改成了正确文件名),但方法仍然抛出找不到文件的异常。
- 方法参数顺序错误:部分小众sftp封装库的
put方法参数顺序为「远端路径、本地路径」,和常用的paramiko规则相反,如果参数写反会尝试读取不存在的远端路径作为本地文件,也会触发该错误。
排查方案
- 在
conn.put()执行前打印fileToPush和pushedFile的实际值,逐个核对两个文件的本地路径是否存在、是否有读权限,远端路径的父目录是否存在、是否有写权限。 - 给每个文件的传输逻辑单独加异常捕获,确认是哪一个文件的传输触发了错误。
- 如果你使用的是paramiko,升级到最新稳定版本后复测,避免旧版本的已知bug影响。
内容的提问来源于stack exchange,提问作者dreami
相关产品推荐
相关产品推荐

