sftp上传下载文件或文件夹

#coding:utf-8import osimport sysimport datetimeimport timeimport paramikoimport statexepath = os.path.dirname(__file__)sys.path.append(exepath)sys.path.append(os.path.join(exepath, '../'))class DownOrUpFile(object): def __init__(self, IP=None, PORT=22, USERNAME=None, PWD=None, PKEY=None): self.ip = IP self.port = PORT self.username = USERNAME self.password = PWD self.PKEY = PKEY def Connet(self): try: if self.password is None: # 如果没有传入密码,则以秘钥方式登录 # 指定本地的RSA私钥文件,如果建立密钥对时设置的有密码,password为设定的密码,如无不用指定password参数 pkey = paramiko.RSAKey.from_private_key_file(self.PKEY) # 建立连接 self.trans = paramiko.Transport((self.ip, self.port)) self.trans.connect(username=self.username, pkey=pkey) # 将sshclient的对象的transport指定为以上的trans self.ssh = paramiko.SSHClient() self.ssh._transport = self.trans # 实例化一个 sftp对象,指定连接的通道 self.sftp = paramiko.SFTPClient.from_transport(self.trans) else: # 连接到IP地址 self.trans = paramiko.Transport((self.ip, self.port)) # 登录 self.trans.connect(username=self.username, password=self.password) # 建立FTP通道 self.sftp = paramiko.SFTPClient.from_transport(self.trans) except Exception as e: print(e) def Close(self): ''' 关闭sftp通道 ''' self.trans.close() def Exec_cmd(self, command): # 执行命令,和传统方法一样 stdin, stdout, stderr = self.ssh.exec_command(command) print(stdout.read().decode()) def makedirs(self, path): try: self.sftp.stat(path) except BaseException as e: filename = os.path.basename(path) path = os.path.dirname(path) self.makedirs(path) try: self.sftp.mkdir(os.path.join(path, filename)) except BaseException as e: raise Exception('create remote path ==>> %s error!!!' %(os.path.join(path, filename))) def UploadFile(self, local_filename, remote_path, okstatus=False, reupload=False): # 判断远程端目录是否存在,如果不存在,则创建 filename = os.path.basename(local_filename) remote_filename = os.path.join(remote_path, filename) PathFlag = False try: self.sftp.stat(remote_path) except BaseException as e: PathFlag = True if PathFlag: # 远程路径不存在 try: print(self.GetStrTime(), '%s is not exist, will be created...' % (remote_path)) # 远程路径不存在,则创建多级目录 self.makedirs(remote_path) except Exception as e: print(e) print('%s Create Fail, will continue ...' %(remote_path)) return False if os.path.isfile(local_filename): try: # 将本地文件写入到远程文件 self.sftp.put(local_filename, remote_filename) print('Success to upload %s ...' %(remote_filename)) except Exception as e: print('Fail to upload %s ...' % (remote_filename)) print(e) else: print('%s is not exist, will be return' %(local_filename)) return False return True def UploadPath(self, local_path, remote_path, okstatus=False, reupload=False, pathupload=False): print('Now, star to upload %s' %(local_path)) fils = os.listdir(local_path) for item in fils : local_filname = os.path.join(local_path, item) remote_filename = os.path.join(remote_path, item) # 如果是文件,则上传该文件,否则,进入该路径后再次循环搜索文件上传 if os.path.isfile(local_filname): self.UploadFile(local_filname, remote_path, okstatus=okstatus, reupload=reupload) elif os.path.isdir(local_filname): # 推送文件夹,判断远程文件目录是否存在,不存在,则需创建文件夹 if pathupload : # 暂不轮循下载目录下载的所有文件夹 self.UploadPath(local_filname, remote_path, okstatus=okstatus, reupload=reupload, pathupload=pathupload) else: print('%s is file folder, will continue it...' %(local_filname)) else: print('%s is error name...' %(local_filname)) def DownloadFile(self, remote_filename, local_path, okstatus=False, redownload=False): ''' 下载文件,成功下载并生成OK,否则生成ERROR :param remote_filename: 远程路径 + 文件名 :param local_path: 本地路径 :param okstatus: 是否输出OK文件,default:False,不输出OK文件, 如果为True,将在文件同级目录下输出《文件名.OK》文件 :param redownload:如果下载目标已存在,是否重新下载该文件 default:False,本地文件已存在,不在重复下载该文件 如果为True,将下载并覆盖该文件 :return: ''' # 判断远程文件是否是一个文件,是文件则下载该文件,否则返回 if stat.S_ISREG(self.sftp.stat(remote_filename).st_mode): # remote is file filename = os.path.basename(remote_filename) if not os.path.isdir(local_path): print('%s is not exist, will be created...' %(local_path)) os.makedirs(local_path) local_filename = os.path.join(local_path, filename) if os.path.isfile(local_filename) and not redownload : print('%s is exist, will continue ...' %(local_filename)) return False else : try: # print('star to download --> %s ...' %(local_filename)) self.sftp.get(remote_filename, local_filename) print('success to download %s ...' %(local_filename)) if okstatus : okname = local_filename + '.OK' self.WriteOK(local_filename, okname) except BaseException as e: print(e) else: print('Remote File %s is not exist, will be return...' %(remote_filename)) return False return True def DownloadPath(self,remote_path, local_path, okstatus=False, redownload=False, pathdownload=False): ''' # 递归方式下载目录下的所有文件 :param remote_path: :param local_path: :return: ''' # 开始对远程目录进行list,列出所有文件和目录 for f in self.sftp.listdir_attr(remote_path): remote_filename = os.path.join(remote_path, f.filename) # 判断是否为文件,是文件则下载,否则递归该目录 if stat.S_ISREG(self.sftp.stat(remote_filename).st_mode): # filename = os.path.basename(remote_filename) # local_filename = os.path.join(local_path, filename) self.DownloadFile(remote_filename, local_path, okstatus=okstatus, redownload=redownload) else: if pathdownload : local_path = os.path.join(local_path, f.filename) if not os.path.isdir(local_path): os.makedirs(local_path) # 暂不轮循下载目录下载的所有文件夹 self.DownloadPath(remote_filename, local_path, okstatus=okstatus, redownload=redownload, pathdownload=pathdownload) else: print('%s is file folder, will continue it...' % (remote_filename)) def JudgeLocalFileExist(self, filename): ''' # 判断文件是否存在,存在则返回True,否则返回False :param filename: :return: ''' if os.path.isfile(filename): print(self.GetStrTime(), '%s is exist, will return True' %(filename)) return True else: print(self.GetStrTime(), '%s is not exist, will return False' % (filename)) return False def JudgeRemoteExist(self, remote): try: self.sftp.stat(remote) if stat.S_ISREG(self.sftp.stat(remote).st_mode): return 1 else: return 2 except BaseException as e: print('JudgeRemoteExist:%s is not exist, will be return ...' % (remote)) print(e) return 0 def JudgeRemotePathExist(self, remote_path): # 判断远程目录是否存在,不存在则退出 try: self.sftp.stat(remote_path) return True except BaseException as e: print('JudgeRemotePathExist:%s is not exist, will be return ...' % (remote_path)) print(e) return False def WriteOK(self, s, okname): ''' 写OK文件,标识文件下载状态 :param s: 输出文件内容 :param okname: OK文件名 :return: ''' try: fp = open(okname, 'w') fp.write(self.GetStrTime() + s) fp.write('\n') fp.close() except BaseException as e: print('create %s error...' %(okname)) print(e) # 获取实时时间,并做格式化处理 def GetStrTime(self, s=None): if not s is None : print(time.strftime('[%Y-%m-%d %H:%M:%S]:', time.localtime(time.time())) + s) return time.strftime('[%Y-%m-%d %H:%M:%S]:', time.localtime(time.time()))