python3向ftp服务器上传和下载封装(包括文件夹的上传和下载)
Posted cui_yonghua
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python3向ftp服务器上传和下载封装(包括文件夹的上传和下载)相关的知识,希望对你有一定的参考价值。
2、python3向ftp服务器上传和下载封装(二)(包括文件夹的上传和下载)
代码如下:
# -*- encoding: utf-8 -*-
import os
import re
import time
import ftplib
class MyFtp(object):
"""Ftp上传下载接口类"""
conn = ftplib.FTP()
def __init__(self, host, port=21):
self.conn.connect(host, port)
self.conn.encoding = "utf-8" # "GB2312"
# self.conn.set_debuglevel(2) # 打开调试级别2,显示详细信息
# self.conn.set_pasv(True) # 0 主动模式 1 #被动模式
def login(self, user, passwd):
"""登录
:param user: 用户名
:param passwd: 密码
:return: 返回self,支持链试调用
"""
self.conn.login(user, passwd)
print(f'self.conn.welcome 登陆成功')
return self
def close(self):
self.conn.quit()
def _is_ftp_dir(self, dir_path):
try:
self.conn.dir(dir_path)
return True
except Exception as e:
print(f'e: e')
return False
def download_file(self, local_file, remote_file):
"""下载单个文件,将 remote_file 下载到 local_file。
:param local_file: 本地文件地址
:param remote_file: 远程目录文件地址
:return: 是否成功标志
"""
ret = True
try:
file_handler = open(local_file, "wb")
self.conn.retrbinary("RETR " + remote_file, file_handler.write)
file_handler.close()
except Exception as err:
ret = False
print(f"file down load err: err")
return ret
def download_dir(self, local_dir, remote_dir, filter=""): # 下载文件夹
"""下载单个文件,将 remote_dir 下载到 local_dir。
:param local_dir: 本地文件夹地址
:param remote_dir: 远程目录文件夹地址
:param filter: 正则过滤器
:return: 是否成功标志
"""
print("远程文件夹 remote_dir:", remote_dir)
if not os.path.exists(local_dir):
os.makedirs(local_dir)
self.conn.cwd(remote_dir)
remote_names = self.conn.nlst()
if 0 == len(remote_names):
print("远程文件目录:", remote_names)
return False
for file in remote_names:
local = os.path.join(local_dir, file)
print("正在下载", self.conn.nlst(file))
if file.find(".") == -1: # 子文件夹递归
if not os.path.exists(local):
os.makedirs(local)
self.download_dir(local, file)
else:
if filter and not re.search(filter, file):
continue
self.download_file(local, file)
self.conn.cwd("..")
return True
def list_dir(self, remote_dir, filter=None, real_path=False):
org_dir = self.conn.pwd()
self.conn.cwd(remote_dir)
file_names = self.conn.nlst()
if filter is not None:
file_names = [v for v in file_names if re.search(filter, v)]
if real_path:
file_names = [os.path.join(remote_dir, v) for v in file_names]
self.conn.cwd(org_dir)
return file_names
def put_file(self, local_file, remote_path="."):
"""上传文件
如果远程路径是个目录,则上传文件到这个目录,文件名不变;如果远程路径的上层是个目录,则上传文件,文件名按照给定命名。
:param local_file: 本地文件
:param remote_path: 远程目录或文件
:return: 是否成功标志
"""
ret = True
ftp_path = remote_path.rstrip('/')
if os.path.isfile(local_file):
file_handler = open(local_file, 'rb')
local_file_name = os.path.basename(local_file)
# 如果远程路径是个目录,则上传文件到这个目录,文件名不变
if self._is_ftp_dir(ftp_path):
self.conn.storbinary(f'STOR os.path.join(ftp_path, local_file_name)', file_handler)
# 如果远程路径的上层是个目录,则上传文件,文件名按照给定命名
elif self._is_ftp_dir(os.path.dirname(ftp_path)):
print(f'STOP ftp_path')
self.conn.storbinary(f'STOR ftp_path', file_handler)
# 如果远程路径不是目录,且上一层的目录也不存在,则提示给定远程路径错误
else:
ret = False
print(f'STOR ftp_path', file_handler)
return ret
def put_dir(self, local_dir, remote_dir=".", begin=True):
"""上传文件夹
:param local_dir: 本地文件夹
:param remote_dir: 远程文件夹
:param begin:
:return: 是否成功标志
"""
ftp_path = remote_dir.rstrip('/')
if not os.path.isdir(local_dir):
print(f'ERROR:The dir:local_dir is not exist')
return False
# 当本地目录存在时上传
# 上传初始化:如果给定的ftp路径不存在需要创建,同时将本地的目录存放在给定的ftp目录下。
# 本地目录下文件存放的路径为ftp_path = ftp_path + os.path.basename(local_path)
# 例如,将本地的文件夹a上传到ftp的a/b目录下,则本地a目录下的文件将上传的ftp的a/b/a目录下
if begin:
if not self._is_ftp_dir(ftp_path):
try:
self.conn.mkd(ftp_path)
except Exception as e:
print(e)
ftp_path = os.path.join(ftp_path, os.path.basename(local_dir))
# 如果上传路径是文件夹,则创建目录
if not self._is_ftp_dir(ftp_path):
try:
self.conn.mkd(ftp_path)
except Exception as e:
print(e)
# 进入本地目录,开始递归查询
os.chdir(local_dir)
local_files = os.listdir('.')
for file in local_files:
ftp_file = os.path.join(ftp_path, file)
# 如果file本地路径是目录则递归上传文件(不需要再进行初始化begin的标志修改为False)
# 如果file本地路径是文件则直接上传文件
if os.path.isdir(file):
self.put_dir(file, ftp_file, False)
print(f' -- time.strftime("%Y-%m-%d %H:%M:%S") success dir: file')
elif "idea" in file:
pass
else:
if 'DS_Store' in file:
continue
self.put_file(file, ftp_path)
print(f' -- time.strftime("%Y-%m-%d %H:%M:%S") success file: file')
# 如果当前本地目录文件已经遍历完毕返回上一层目录
os.chdir('..')
print(f'finish')
if __name__ == '__main__':
my_ftp_info = MyFtp(host='192.168.38.40')
login_result = my_ftp_info.login(user='', passwd='')
print(login_result)
以上是关于python3向ftp服务器上传和下载封装(包括文件夹的上传和下载)的主要内容,如果未能解决你的问题,请参考以下文章