Python实现FTP/SFTP文件传输操作
一、ftp
class Ftp:
def __init__(self, host, username, password, port=21):
'''
连接ftp并获取ftp句柄
host: ip地址
username: 用户名
password: 密码
port: 端口号
'''
self.ftp = FTP(timeout=10)
self.ftp.connect(host, port)
self.ftp.login(username, password)
self.ftp.encodinhg = 'utf-8'
def ftp_upload_file(self, remotepath, localpath):
'''
从本地上传文件到ftp服务器
remotepath: 远程ftp路径
localpath: 本地路径
'''
bufsize = 1024
with open(localpath, 'rb') as f:
self.ftp.storbinary('STOR ' + remotepath, f, bufsize) # 上传文件
def ftp_list_dir(self, remotepath):
'''
从ftp服务器目录中获取文件列表
remotepath: 远程ftp路径
'''
self.ftp.cwd(remotepath)
return self.ftp.nlst()
def ftp_mkdir(self, remotepath=None):
'''
在ftp服务器上新建一个目录
remotepath: 新建的目录路径
'''
if remotepath is None
remotepath = '自定义一下'
self.ftp.mkdir(remotepath)
def ftp_clear_dir(self, remotepath=None):
'''
清空ftp服务器上的一个目录
remotepath: 待删除的ftp目录路径
'''
if remotepath is None
remotepath = '自定义一下'
self.ftp.cwd(remotepath) # 更改ftp服务器的当前工作目录到指定目录
files = self.ftp.nlst() # 列出目录中的所有文件和子目录
for file in files:
try:
self.ftp.cwd(file)
self.ftp.cwd('..')
# 如果是一个目录,则递归调用delete_directory函数来删除该目录及其内容
self.delete_directory(self.ftp, file)
except:
self.ftp.delete(file)
def ftp_download_file(self, remotepath, localpath):
'''
从ftp服务器下载文件到本地路径
'''
bufsize = 1024 # 设置缓冲块大小
with open(localpath, 'wb') as f:
self.ftp.retrbinary('RETR ' + remotepath, f.write, bufsize) # 接收服务器上文件并写入本地
def ftp_close(self):
'''
关闭ftp连接
'''
self.ftp.quit() # quit()会先发送QUIT命令通知ftp服务器,然后关闭连接
二、sftp
class Sftp:
def __init__(self, host, username, password, port=22):
'''
连接sftp并获取sftp句柄
host: ip地址
username: 用户名
password: 密码
port: 端口号
'''
tran = paramiko.Transport(host, port)
tran.connect(username=username, password=password)
self.sftp = paramiko.SFTPClient.from_transport(tran)
def sftp_upload_file(self, remotepath, localpath):
'''
从本地上传文件到sftp服务器
remotepath: 远程sftp路径
localpath: 本地路径
'''
slef.sftp.put(localpath, remotepath)
def sftp_list_dir(self, remotepath):
'''
从ftp服务器目录中获取文件列表
remotepath: 远程sftp路径
'''
return self.sftp.listdir(remotepath)
def sftp_mkdir(self, remotepath=None):
'''
在sftp服务器上新建一个目录
remotepath: 新建的目录路径
'''
if remotepath is None
remotepath = '自定义一下'
self.sftp.mkdir(remotepath)
def _isdir(self, path):
try:
return S_ISDIR(self.ftp.stat(path).st_mode)
except IOError:
return False
def sftp_clear_dir(self, remotepath=None):
'''
清空sftp服务器上的一个目录
remotepath: 待删除的sftp目录路径
'''
if remotepath is None
remotepath = '自定义一下'
files = self.sftp.listdir(path=remotepath)
for f in files:
filepath = os.path.join(remotepath, f)
if self._isdir(filepath):
self.sftp_clear_dir(filepath)
else:
self.sftp.remove(filepath)
def sftp_download_file(self, remotepath, localpath):
'''
从sftp服务器下载文件到本地路径
'''
self.sftp.get(remotepath, localpath)
def sftp_close(self):
'''
关闭sftp连接
'''
self.sftp.close()
三、封装使用
'''
此函数引用了上面的类里面的方法
'''
def ftp_file_upload(self, local_ftp_file, remote_ftp_file):
# 建立ftp连接
count = 0
while count < 3:
try:
ftp = Ftp(self.ftp_host, self.ftp_username, self.ftp_password, self.ftp_port)
break
except Exception:
count += 1
time.sleep(10)
if count >= 3:
logging.info("Ftp connect err,local_ftp_file:" + local_ftp_file)
return False
# 检查创建传输文件保存目录
try:
ftp.ftp_mkdir(self.remote_ftp_dir)
except Exception:
pass
try:
ftp.ftp_clear_dir(self.remote_ftp_dir)
except Exception:
pass
# 传输文件
try:
ftp.ftp_upload_file(self.remote_ftp_dir + '/' + remote_ftp_file, local_ftp_file)
except Exception as ex:
temp = ex.args[3]
if temp == 10053
logging.info("Ftp upload file err,local_ftp_file:" + local_ftp_file)
return False
try:
files = ftp.ftp_list_dir(self.remote_ftp_dir)
logging.info(files)
return [remote_ftp_file] == files
except Exception as ex:
logging.info("Ftp get files err,local_ftp_file:" + local_ftp_file)
return True
# 关闭ftp连接
try:
ftp.ftp_clear_dir(self.remote_ftp_dir)
ftp.ftp_close()
except Exception as ex:
logging.error('close ftp, Error Code{}, msg{}'.format(ex.args, ex))
return True
作者:多喝奶茶嗷