python sftp传输文件总是报文件不存在_python脚本---上传本机文件到远端(接上文)...

本文介绍了一个使用paramiko模块在Python中实现本地文件到Linux服务器的SFTP同步脚本。通过遍历本地目录,比较已上传文件记录,找到待上传文件并上传,同时处理远程目录的创建。在遇到目录不存在的情况下,不支持递归创建。
摘要由CSDN通过智能技术生成

上一个脚本刚写完,第二天不用了。。。需要传到linux服务器上。。。

So,下一个脚本开始:

1. 这次选择用的paramiko模块

pip install paramiko

2. 整体思路

遍历本地目录放入集合

读取上次上传到linux的文件信息(existsfile.log)放入另一个集合

两个集合取补集(好像叫对称差集吧)

上传补集内的文件

远程目录必须存在,put方法的远程目录才有效。而且必须是文件的绝对路径,不能是文件夹路径,否则也会失败;mkdir方法一样,不可以递归地创建目录,在这两个地方坑了好久。

3. 代码实现

syncfiles.py

# -*- coding: utf-8 -*-

__author__ = "hand"

import os

import paramiko

import settings

import platform

from datetime import datetime

class SyncFiles(object):

"""

复制本机文件到远端

"""

def __init__(self):

self.f = open("existsfile.log", "a+")

self.remote_host = settings.REMOTE_HOST

self.remote_port = settings.REMOTE_PORT

self.remote_user = settings.REMOTE_USER

self.remote_pwd = settings.REMOTE_PWD

if settings.REMOTE_PATH[-1] == '/' or settings.REMOTE_PATH[-1] == '\\':

self.remote_path = settings.REMOTE_PATH[0:-1]

else:

self.remote_path = settings.REMOTE_PATH

if settings.LOCAL_PATH[-1] == '/' or settings.LOCAL_PATH[-1] == '\\':

self.local_path = settings.LOCAL_PATH[0:-1]

else:

self.local_path = settings.LOCAL_PATH

def get_upload_files(self):

"""获取待上传的所有文件"""

local_path_set = set() # 本地文件

file_transfered_set =set() # 已经上传过的文件

for root, dirs, files in os.walk(self.local_path):

for file in files:

local_file = os.path.join(root, file) # 完整的文件路径:/A/B/C/1.txt

local_path_set.add(local_file)

self.f.seek(0,0) # 将记录文件指针放在文件头,用于读文件

for line in self.f.readlines():

file_transfered = line.split("-")[-1].strip()

file_transfered_set.add(file_transfered)

ready_upload_set = local_path_set ^ file_transfered_set # 待上传的文件

return list(ready_upload_set)

def record_log(self, path):

now = datetime.now()

# if platform.platform().startswith("Windows"):

# self.f.write(now.strftime('%Y/%M/%d %H:%M:%S %A ') + ' - ' + path + '\\r\\n')

# else:

self.f.write(now.strftime('%Y/%M/%d %H:%M:%S %A ') + ' - ' + path + '\n')

def transfile(self):

"""上传文件"""

try:

# 实例化Transport

trans = paramiko.Transport((self.remote_host, 22))

# 建立连接

trans.connect(username=self.remote_user, password=self.remote_pwd)

# 实例化一个sftp对象

sftp = paramiko.SFTPClient.from_transport(trans)

ready_upload_list = self.get_upload_files()

already_dir = [] # 存放远端新建的目录

if ready_upload_list:

for local_file_path in ready_upload_list:

if platform.platform().startswith("Windows"):

file_need = local_file_path.replace(self.local_path, '').replace('\\','/') # 取出本地路径后,需要同步到远端的部分:B/C/1.txt

else:

file_need = local_file_path.replace(self.local_path, '')

remote_file_path = self.remote_path + file_need

try:

# 上传文件,必须是文件的完整路径,远端的目录必须已经存在

sftp.put(localpath=local_file_path, remotepath=remote_file_path)

self.record_log(local_file_path)

except Exception as e:

# 如果目录不存在就创建,但是不支持递归创建

dir_need_list = os.path.split(file_need)[0].split("/") # B、C

dir1 = ''

print dir_need_list

for dir in dir_need_list[1:]:

if dir not in already_dir:

# 目录存在会报错,所以把新建过的目录存在一个全局列表中

if platform.platform().startswith("Windows"):

sftp.mkdir(os.path.join(self.remote_path, dir1, dir).replace('\\','/'))

else:

sftp.mkdir(os.path.join(self.remote_path, dir1, dir))

dir1 = dir

already_dir.append(dir) # 新建过的目录存在一个全局列表中

# 再次执行

sftp.put(localpath=local_file_path, remotepath=remote_file_path)

self.record_log(local_file_path)

except Exception as e:

pass

finally:

trans.close()

if __name__ == "__main__":

sf = SyncFiles()

sf.transfile()

settings.py

# -*- coding: utf-8 -*-

__author__ = "hand"

REMOTE_HOST = 'X.X.X.X'

REMOTE_PORT = 22

REMOTE_USER = '用户名'

REMOTE_PWD = '密码'

REMOTE_PATH = '/storage/zhaoning/ttt'

LOCAL_PATH = '/Users/smallcaff/Desktop/filetest'

4. 参考

看过其他一些人的代码,也拉下来测试过,有的好像在创建远端目录时有问题,不知道跟版本有关系没

这篇博客关于paramiko用法写的很详细,paramiko用法没有看官方教程,参考了这个:python模块之 paramiko

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值