sftp下載 上傳
"""使用paramiko模組中的sftp登陸遠端主機,實現上傳和下載功能"""
# 根據輸入引數判斷是檔案還是目錄,進行上傳和下載
# 本地引數local需要與遠端引數remote型別一致,檔案以檔名結尾,目錄以\結尾
# 上傳和下載的本地和遠端目錄需要存在
# 異常捕獲
import paramiko
import os
import logging
from stat import S_ISDIR as isdir
import re
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
class Sftp(object):
def __init__(self, ip, username, password):
self.ip = ip
self.username = username
self.password = password
self.sftp = self.connect()
def connect(self):
try:
t = paramiko.Transport((self.ip, 22)) # 建立連線
# logging.info(self.ip)
t.connect(username=self.username, password=self.password)
sftp = paramiko.SFTPClient.from_transport(t)
return sftp
# logging.info(self.sftp)
# return sftp
except Exception as e:
logging.info(e)
# # 獲取單個檔案
# def get(self, remotefile, localfile):
#
# self.sftp.get(remotefile, localfile)
#
# # 上傳單個檔案
# def put(self, localfile, remotefile):
#
# self.sftp.put(localfile, remotefile)
# 獲取目錄 所有檔案
def __get_all_file(self, remote_dir):
all_files = list()
# 去掉路徑字串最後的字元'/',如果有的話
if remote_dir[-1] == '/':
remote_dir = remote_dir[0:-1]
# 獲取當前指定目錄下的所有目錄及檔案,包含屬性值
# logging.info(sftp)
files = self.sftp.listdir_attr(remote_dir)
for i in files:
# 如果是檔案 remote_dir目錄中的完整路徑
filename = remote_dir + '/' + i.filename
# logging.info(filename)
# 如果是目錄,遞迴處理該目錄
if isdir(i.st_mode):
if not os.path.exists(i.filename):
os.makedirs(i.filename)
all_files.extend(self.__get_all_file(filename))
else:
all_files.append(filename)
return all_files
def get_dir(self, remote_dir, local_dir):
all_files = self.__get_all_file(remote_dir)
for x in all_files:
filepath = re.split('[:/]', x)
filename = filepath[-1]
local_path = local_dir + os.sep + '/'.join(filepath[1:-1])
if not os.path.exists(local_path):
os.makedirs(local_path)
local_filename = os.path.join(local_path, filename)
print(u'get檔案{}傳輸中'.format(filename))
# logging.info(sftp)
self.sftp.get(x, local_filename)
def __put_all_file(self, local_dir):
# 儲存所有檔案的列表
all_files = list()
# 獲取當前指定目錄下的所有目錄及檔案 或目錄的完整路徑
files = os.listdir(local_dir)
for i in files:
# local_dir目錄中每一個檔案或目錄的完整路徑
filename = os.path.join(local_dir, i)
# 是目錄就遞迴處理
if os.path.isdir(i):
all_files.extend(self.__put_all_file(filename))
else:
all_files.append(filename)
return all_files
def put_dir(self, local_dir, remote_dir):
# 去掉字串最後的字元
if remote_dir[-1] == '/':
remote_dir = remote_dir[0:-1]
# 獲取本地指定的目錄及目錄下的檔案
all_files = self.__put_all_file(local_dir)
for i in all_files:
filename = os.path.split(i)[-1]
remote_filename = remote_dir + '/' + filename
print(u'Put檔案{}傳輸中...'.format(filename))
self.sftp.put(i, remote_filename)
if __name__ == '__main__':
remote_path = '/upload'
local_path = '/home/python/Desktop/'
host = Sftp('47.104.236.156', 'test', 'test123')
# 將遠端remote_path目錄中的所有檔案get到本地local_path目錄
host.get_dir(remote_path, local_path)
# host.put_dir(local_path, remote_path)