ftp
#!/usr/bin/python
# -*- coding: UTF-8 -*-
from ftplib import FTP
import os
class MyFtp:
def __init__(self, host=None, port=21, username=None, password=None):
self.ftp = FTP()
# 重新设置下编码方式
self.ftp.encoding = 'utf-8'
try:
# 0主动模式 1 #被动模式
self.ftp.set_pasv(True)
self.ftp.connect(host, port)
self.ftp.login(username, password)
print('成功连接到:', host, "登录成功...")
except Exception as err:
print("FTP 连接或登录失败,错误描述为:", err)
def __del__(self):
print("关闭连接")
self.ftp.quit()
def is_same_size(self, local_file, remote_file):
# 判断文件大小是否相等
try:
remote_file_size = self.ftp.size(remote_file)
except Exception as err:
# print("is_same_size() 错误描述为:%s" % err)
remote_file_size = -1
try:
local_file_size = os.path.getsize(local_file)
except Exception as err:
# print("is_same_size() 错误描述为:%s" % err)
local_file_size = -1
# print(f'local_file_size:{local_file_size}, remote_file_size:{remote_file_size}')
if remote_file_size == local_file_size:
return 1
else:
return 0
def download_file(self, remote_file, local_file):
remote_file = remote_file if self.ftp.pwd() == "/" else self.ftp.pwd() + "/" + remote_file
print(f"下载文件: {remote_file} ---> {local_file}")
if self.is_same_size(local_file, remote_file):
print("文件大小相同,此文件跳过")
else:
try:
buf_size = 1024
file_handler = open(local_file, 'wb')
self.ftp.retrbinary(f'RETR {remote_file}', file_handler.write, blocksize=buf_size)
file_handler.close()
except Exception as err:
print(f'下载文件出错,出现异常:{err}')
def download_dir(self, remote_dir, local_dir):
remote_dir = remote_dir if self.ftp.pwd() == "/" else self.ftp.pwd() + "/" + remote_dir
print(f"下载目录: {remote_dir} ---> {local_dir}")
try:
self.ftp.cwd(remote_dir)
print(f'切换至目录: {self.ftp.pwd()}')
except Exception as err:
print(f'远程目录{remote_dir}不存在,继续...,具体错误描述为:{err}')
return
os.makedirs(local_dir, exist_ok=True)
remote_dirs = []
self.ftp.dir(".", remote_dirs.append)
remote_list = list(map(lambda x: x.split()[-1], remote_dirs))
print(f'远程目录列表: {remote_list}')
for remote_detail in remote_dirs:
file_type = remote_detail[0]
file_name = remote_detail.split()[-1]
local_path = os.path.join(local_dir, file_name)
if file_type == "d":
self.download_dir(file_name, local_path)
elif file_type == '-':
self.download_file(file_name, local_path)
self.ftp.cwd("..")
print("返回上层目录: ", self.ftp.pwd())
def upload_file(self, local_file, remote_file):
# 上传文件
remote_file = remote_file if self.ftp.pwd() == "/" else self.ftp.pwd() + "/" + remote_file
print(f"上传文件: {local_file} ---> {remote_file}")
if not os.path.isfile(local_file):
print(f'{local_file} 不存在')
return
if self.is_same_size(local_file, remote_file):
print('文件大小相同,此文件跳过')
return
try:
buf_size = 1024
file_handler = open(local_file, 'rb')
self.ftp.storbinary(f'STOR {remote_file}', file_handler, buf_size)
file_handler.close()
except Exception as err:
print(f'上传文件出错,出现异常:{err}')
def upload_dir(self, local_dir, remote_dir):
# 上传目录
remote_dir = remote_dir if self.ftp.pwd() == "/" else self.ftp.pwd() + "/" + remote_dir
print(f"上传目录: {local_dir} ---> {remote_dir}")
if not os.path.isdir(local_dir):
print(f'本地目录 {local_dir} 不存在')
return
try:
self.ftp.mkd(remote_dir)
except Exception as err:
print(f"创建远程目录{remote_dir}失败,错误描述为:{err}")
return
self.ftp.cwd(remote_dir)
print('切换至远程目录: ', self.ftp.pwd())
local_name_list = os.listdir(local_dir)
print("本地目录列表: ", local_name_list)
for local_name in local_name_list:
local_name_path = os.path.join(local_dir, local_name)
if os.path.isdir(local_name_path):
self.upload_dir(local_name_path, local_name)
else:
self.upload_file(local_name_path, local_name)
self.ftp.cwd("..")
print("返回上层目录: ", self.ftp.pwd())
sftp
#!/usr/bin/python
# coding=utf-8
import paramiko
import os
import stat
class MySftp:
def __init__(self, host=None, port=22, username=None, password=None):
self.sftp_connect = paramiko.Transport((host, port))
self.sftp_connect.connect(username=username, password=password)
self.sftp = paramiko.SFTPClient.from_transport(self.sftp_connect)
print('成功连接到:', host, "登录成功...")
def __del__(self):
print("关闭连接")
self.sftp_connect.close()
def is_same_size(self, local_file, remote_file):
# 判断文件大小是否相等
try:
remote_file_size = self.sftp.stat(remote_file).st_size
except Exception as err:
# print("is_same_size() 错误描述为:%s" % err)
remote_file_size = -1
try:
local_file_size = os.path.getsize(local_file)
except Exception as err:
# print("is_same_size() 错误描述为:%s" % err)
local_file_size = -1
# print(f'local_file_size:{local_file_size}, remote_file_size:{remote_file_size}')
if remote_file_size == local_file_size:
return 1
else:
return 0
def download_file(self, remote_file, local_file):
remote_file = self.sftp.getcwd() + "/" + remote_file if self.sftp.getcwd() else remote_file
print(f"下载文件:{remote_file} ---> {local_file}")
if self.is_same_size(local_file, remote_file):
print("文件已存在且文件已存在且文件大小相同,此文件跳过")
return
try:
self.sftp.get(remote_file, local_file)
except Exception as err:
print(f'下载文件出错,出现异常:{err}')
def download_dir(self, remote_dir, local_dir):
remote_dir = self.sftp.getcwd() + "/" + remote_dir if self.sftp.getcwd() else remote_dir
print(f"下载目录: {remote_dir} ---> {local_dir}")
try:
self.sftp.chdir(remote_dir)
print(f'切换至目录: {self.sftp.getcwd()}')
except Exception as err:
print(f'远程目录{remote_dir}不存在,继续...,具体错误描述为:{err}')
return
os.makedirs(local_dir, exist_ok=True)
remote_dirs = self.sftp.listdir(remote_dir)
print(f'远程目录列表: {remote_dirs}')
for remote_path in remote_dirs:
local_path = os.path.join(local_dir, remote_path)
if str(self.sftp.stat(remote_path))[0] == "d":
self.download_dir(remote_path, local_path)
elif str(self.sftp.stat(remote_path))[0] == "-":
self.download_file(remote_path, local_path)
self.sftp.chdir("..")
print("返回上层目录: ", self.sftp.getcwd())
def upload_file(self, local_file, remote_file):
remote_file = self.sftp.getcwd() + "/" + remote_file if self.sftp.getcwd() else remote_file
print(f"上传文件: {local_file} ---> {remote_file}")
if not os.path.isfile(local_file):
print(f"本地文件 {local_file} 不存在")
return
if self.is_same_size(local_file, remote_file):
print('文件已存在且文件大小相同,此文件跳过')
return
try:
self.sftp.put(local_file, remote_file)
except Exception as err:
print(f'上传文件出错,出现异常:{err}')
def upload_dir(self, local_dir, remote_dir):
remote_dir = self.sftp.getcwd() + "/" + remote_dir if self.sftp.getcwd() else remote_dir
print(f"上传目录: {local_dir} ---> {remote_dir}")
if not os.path.isdir(local_dir):
print(f'本地目录 {local_dir} 不存在')
return
if not self.is_sftp_dir(remote_dir):
self.sftp.mkdir(remote_dir)
self.sftp.chdir(remote_dir)
print('切换至远程目录: ', self.sftp.getcwd())
local_name_list = os.listdir(local_dir)
print("本地目录列表: ", local_name_list)
for local_name in local_name_list:
local_name_path = os.path.join(local_dir, local_name)
if os.path.isdir(local_name_path):
self.upload_dir(local_name_path, local_name)
else:
self.upload_file(local_name_path, local_name)
self.sftp.chdir("..")
print("返回上层目录: ", self.sftp.getcwd())
def is_sftp_dir(self, remote_dir):
try:
if stat.S_ISDIR(self.sftp.stat(remote_dir).st_mode): # 如果remote_dir存在且为目录,则返回True
return True
except:
return False