paramiko批量上传下载sftp,解决访问windows系列sftp乱码问题
2021-03-10 19:29
标签:exists 删除本地文件 expec 创建 win mdi ror span join 找到paramiko下的py3compat文件,将以下4个函数内的编码改成‘gbk’ paramiko批量上传下载sftp,解决访问windows系列sftp乱码问题 标签:exists 删除本地文件 expec 创建 win mdi ror span join 原文地址:https://www.cnblogs.com/angelyan/p/12670444.html一、封装代码
import os
import paramiko
from stat import S_ISDIR
import shutil
class ConnectSftp(object):
def __init__(self,ip,port,username,password):
self.ip=ip
self.port=port
self.username=username
self.password=password
self.connect()
def connect(self):
self.transport = paramiko.Transport((self.ip, self.port))
self.transport.connect(username=self.username, password=self.password)
self.sftp = paramiko.SFTPClient.from_transport(self.transport)
def close(self):
self.transport.close()
def isdir(self,path):
try:
return S_ISDIR(self.sftp.stat(path).st_mode)
except IOError:
return False
def sftp_rm(self,path):
files = self.sftp.listdir(path=path)
for f in files:
filepath = os.path.join(path, f)
if self.isdir(filepath):
self.sftp_rm(filepath)
else:
self.sftp.remove(filepath)
self.sftp.rmdir(path)
def local_to_sftp(self,local_dir_name,remote_dir_name,move_state=False):
‘‘‘
:param local_dir_name: 本地文件夹路径
:param remote_dir_name: sftp文件夹路径
:param move_state: 是否删除本地文件夹
:return:
‘‘‘
if os.path.isdir(local_dir_name):
# 文件夹,不能直接下载,需要继续循环
self.check_sftp_dir(remote_dir_name)
for remote_file_name in os.listdir(local_dir_name):
sub_local = os.path.join(local_dir_name, remote_file_name)
sub_local = sub_local.replace(‘\\‘, ‘/‘)
sub_remote = os.path.join(remote_dir_name, remote_file_name)
sub_remote = sub_remote.replace(‘\\‘, ‘/‘)
print(sub_local, sub_remote)
self.local_to_sftp(sub_local, sub_remote)
else:
# 文件,直接上传
print(‘开始上传文件:‘ + local_dir_name)
self.sftp.put(local_dir_name, remote_dir_name)
if move_state:
shutil.rmtree(local_dir_name)
def sftp_to_local(self,remote_dir_name,local_dir_name,move_state=False):
‘‘‘
:param remote_dir_name: sftp文件夹路径
:param local_dir_name: 本地文件夹路径
:param move_state: 是否删除sftp文件夹
:return:
‘‘‘
try:
self.sftp.stat(remote_dir_name)
except Exception:
raise BaseException({"error":"sftp路径不存在"})
remote_file = self.sftp.stat(remote_dir_name)
if S_ISDIR(remote_file.st_mode):
# 文件夹,不能直接下载,需要继续循环
self.check_local_dir(local_dir_name)
print(‘开始下载文件夹:‘ + remote_dir_name)
for remote_file_name in self.sftp.listdir(remote_dir_name):
sub_remote = os.path.join(remote_dir_name, remote_file_name)
sub_remote = sub_remote.replace(‘\\‘, ‘/‘)
sub_local = os.path.join(local_dir_name, remote_file_name)
sub_local = sub_local.replace(‘\\‘, ‘/‘)
self.sftp_to_local(sub_remote, sub_local)
else:
# 文件,直接下载
print(‘开始下载文件:‘ + remote_dir_name)
self.sftp.get(remote_dir_name, local_dir_name)
if move_state:
self.sftp_rm(remote_dir_name)
def check_local_dir(self, local_dir_name):
"""本地文件夹是否存在,不存在则创建"""
if not os.path.exists(local_dir_name):
os.makedirs(local_dir_name)
def check_sftp_dir(self, remote_dir_name):
"""sftp文件夹是否存在,不存在则创建"""
try:
self.sftp.stat(remote_dir_name)
except IOError as e:
self.sftp.mkdir(remote_dir_name)
def cmd(self, command):
ssh = paramiko.SSHClient()
ssh._transport = self.transport
stdin, stdout, stderr = ssh.exec_command(command)
print(stdout)
result = stdout.read()
return result
cs=ConnectSftp(‘ip‘,port,‘name‘,‘pwd‘)
if __name__ == ‘__main__‘:
cs.local_to_sftp(r"本地路径",‘sftp路径‘,move_state=True)
cs.sftp_to_local("sftp路径",r"本地路径",move_state=True)
cs.close()
二、解决windows2008-sftp文件路径乱码
def b(s, encoding="gbk"):
"""cast unicode or bytes to bytes"""
if isinstance(s, bytes):
return s
elif isinstance(s, str):
return s.encode(encoding)
else:
raise TypeError("Expected unicode or bytes, got {!r}".format(s))
def u(s, encoding="gbk"):
"""cast bytes or unicode to unicode"""
if isinstance(s, bytes):
return s.decode(encoding)
elif isinstance(s, str):
return s
else:
raise TypeError("Expected unicode or bytes, got {!r}".format(s))
def b(s, encoding="gbk"): # NOQA
"""cast unicode or bytes to bytes"""
if isinstance(s, str):
return s
elif isinstance(s, unicode): # NOQA
return s.encode(encoding)
elif isinstance(s, buffer): # NOQA
return s
else:
raise TypeError("Expected unicode or bytes, got {!r}".format(s))
def u(s, encoding="gbk"): # NOQA
"""cast bytes or unicode to unicode"""
if isinstance(s, str):
return s.decode(encoding)
elif isinstance(s, unicode): # NOQA
return s
elif isinstance(s, buffer): # NOQA
return s.decode(encoding)
else:
raise TypeError("Expected unicode or bytes, got {!r}".format(s))
文章标题:paramiko批量上传下载sftp,解决访问windows系列sftp乱码问题
文章链接:http://soscw.com/index.php/essay/62896.html