当前位置 : 主页 > 编程语言 > python >

Python操作FTP服务器实现文件和文件夹的上传与下载,python清理ftp目录下的所有文

来源:互联网 收集:自由互联 发布时间:2022-06-18
Python 连接 FTP 服务器并实现文件夹上传实例演示 ​​第一章:连接 FTP 服务器并实现文件夹上传​​ ​​① 连接 FTP 服务器​​ ​​② 区分文件和文件夹名​​ ​​③ 文件夹名包含



Python 连接 FTP 服务器并实现文件夹上传实例演示

  • ​​第一章:连接 FTP 服务器并实现文件夹上传​​
  • ​​① 连接 FTP 服务器​​
  • ​​② 区分文件和文件夹名​​
  • ​​③ 文件夹名包含空格处理​​
  • ​​④ 使用递归实现:清理指定目录下所有的文件和非空文件夹​​
  • ​​⑤ 使用递归实现:本地文件上传FTP服务器里的文件夹​​
  • ​​第二章:相关问题​​
  • ​​① 上传的文件名包含中文【'utf-8' codec can't decode byte ...】​​
  • ​​② 指定的路径存在问题【550 The system cannot find the file specified.】​​
  • ​​③ 上传文件前未加STOR标识【500 Command not understood.】​​
  • ​​④ 上传文件夹包含中文名【暂未解决】​​


​[ 系列文章 ]​

​​Python​ 连接 ​FTP​ 服务器并实现文件夹下载实例演示​​

第一章:连接 FTP 服务器并实现文件夹上传

① 连接 FTP 服务器

如果 ​FTP​ 不用用户名密码就直接可以访问,那就是用的默认用户名 ​Anonymous​,密码为空。

# -*- coding: UTF8 -*-
# 2022-3-10
# 作者:小蓝枣
# python连接ftp服务器
from ftplib import FTP

def conn_ftp():
'''
作用:连接ftp服务器
参数:无
返回:ftp服务器连接的对象
'''

# FTP连接信息
ftp_ip = "xx.xx.xx.xx"
# 默认端口21
ftp_port = 21
# 如果未指定,使用默认用户名为Anonymous,密码为空
ftp_user = "Anonymous"
ftp_password = ""

ftp = FTP()
# 连接ftp
ftp.connect(ftp_ip, ftp_port)
# ftp登录
ftp.login(ftp_user, ftp_password)
# 查看欢迎信息
print(ftp.getwelcome())

return ftp

ftp = conn_ftp()

② 区分文件和文件夹名

从方法 ​​ftp.dir()​​​ 返回结果可以看到包含 ​​<DIR>​​ 标识的为文件夹,我们根据这个特征来进行文件夹区分。

def diff_dir(ftp, path):
'''
作用:区分文件和文件夹
参数1:ftp连接对象
参数2:要展示的目录
返回:无
'''

# 进入指定目录
ftp.cwd(path)
# 显示当前所在位置
print("当前所在位置为:")
print(ftp.pwd())
# 展示目录内容
print("\n显示目录内容:")
dirs = []
ftp.dir(".", dirs.append)
for i in dirs:
# 区分文件和文件夹
if("<DIR>" in i):
print("目录为:" + i.split(" ")[-1])
else:
print("文件为:" + i.split(" ")[-1])

path = "/CaseData/nc.vo.sdp.testcase.testcase.TestcaseHVO/"
diff_dir(ftp, path)

Python操作FTP服务器实现文件和文件夹的上传与下载,python清理ftp目录下的所有文件和非空文件夹_上传

③ 文件夹名包含空格处理

​​split(" ")[-1]​​ 方法有个缺陷,如果文件或文件夹名里包含空格,得到到的文件夹名就不对了,下面的方法可以有效的解决这个问题

def get_dir_name(s):
'''
作用:需要文件或文件夹名
参数1:需要截取的字符串
返回:文件或文件夹名
'''
dir_name = ""
k = 0
record = ""
for i in s:
if(record == " " and i != " "):
k = k + 1;
if(k >= 3):
dir_name = dir_name + i;
record = i

print(dir_name)
return dir_name

# 测试两条数据
get_dir_name("03-08-22 09:52AM <DIR> C2021.11_ZDHJC_004a")
get_dir_name("03-08-25 10:32AM 89098 hello .exe")

Python操作FTP服务器实现文件和文件夹的上传与下载,python清理ftp目录下的所有文件和非空文件夹_python_02

④ 使用递归实现:清理指定目录下所有的文件和非空文件夹

为什么强调非空呢,因为如果文件夹非空是没法直接删除的,只有当文件夹里的所有内容都删掉,文件夹为空时才可以删除。

import os

def dir_clear(ftp, dir_name):
'''
作用: 目录清空处理
参数1:ftp连接对象
参数2:目录或文件名
返回:无
'''
# 进入指定目录
ftp.cwd(dir_name)

dirs = []
ftp.dir(".", dirs.append)
for i in dirs:
try:
if("<DIR>" in i):
new_dir_name = get_dir_name(i)
# 非空目录还删不了,先删除目录里的文件
dir_clear(ftp, new_dir_name)
ftp.rmd(new_dir_name)
elif("<DIR>" not in i):
new_file_name = get_dir_name(i)
ftp.delete(new_file_name)
except Exception as e:
print("删除失败脚本:" + get_dir_name(i))
print("失败原因:" + e)

# 退出当前目录
ftp.cwd("..")

path = "/CaseData/nc.vo.sdp.testcase.testcase.TestcaseHVO/"
# 文件清空
dir_clear(ftp, path)

执行后可以看到所有的文件和文件夹都被清空了:

Python操作FTP服务器实现文件和文件夹的上传与下载,python清理ftp目录下的所有文件和非空文件夹_开发语言_03

⑤ 使用递归实现:本地文件上传FTP服务器里的文件夹


​思路: 1、并判断是否是目录,如果是目录的话,本地根据目录结构进行递归,同时在 ​FTP​ 服务器的对应位置创建文件夹。
2、需要判断原来的目录下是否存在同名的文件或文件夹,是的话要进行删除,这里用 ​​delete_dir()​​ 方法来实现,非空文件夹不能直接删除,还要进行递归处理,用上面的 ​​dir_clear()​​ 方法来实现。
3、由于文件和文件夹可以同名,但是不是同一种类型,怕误删,这里根据同名并同种类型来判断,如果原来列表里的文件较多,判断同类型的方法需要列表遍历,再加上上传的文件较多就会反复遍历列表影响效率,所以加个 ​​current_dir​​ 字符串的变量,可以先检查是否有同名的,如果没有直接跳过,提升效率,有的话再进行二次遍历。


​注意​:由于是一个 ​ftp​ 连接对象,递归过程中进去某个目录下,递归结束要回到之前的目录。

import pathlib

def delete_dir(ftp, isdir, dir_name, current_dir):
'''
作用: 判断目录或文件是否存在,存在的话删除
参数1:ftp连接对象
参数2:是否为目录,是的话为目录,不是的话为文件
参数3:目录或文件名
参数4:当前目录下的列表文件名集
返回:无
'''
# 先初步判断下,不然直接循环遍历量大的影响效率
if(dir_name not in current_dir):
return

dirs = []
ftp.dir(".", dirs.append)
for i in dirs:
if(isdir == True and "<DIR>" in i):
if(dir_name == get_dir_name(i)):
# 非空目录还删不了,先删除目录里的文件
dir_clear(ftp, dir_name)
ftp.rmd(dir_name)
elif(isdir == False and "<DIR>" not in i):
if(dir_name == get_dir_name(i)):
ftp.delete(dir_name)


def upload_dir(ftp, path, local_path):
'''
作用: 上传目录
参数1:ftp连接对象
参数2:远程路径
参数3:本地存放路径
返回:无
'''

print(path)
# 进入指定目录
ftp.cwd(path)

# 获取当前目录的一个列表
current_dir = ""
for i in ftp.nlst():
current_dir = current_dir + " " + i

# 遍历本地路径
for i in os.listdir(local_path):
new_local_path = local_path + '/' + i
# 判断为文件
if(os.path.isfile(new_local_path)):
# 如果有同名文件,删除
delete_dir(ftp, False, i, current_dir)
f = open(new_local_path, 'rb')
# 上传文件
ftp.storbinary("STOR " + i, f)
f.close()
# 判断为文件夹
elif(os.path.isdir(new_local_path)):
# 如果有同名文件夹,删除
delete_dir(ftp, True, i, current_dir)
# 创建目录
print(i)
try:
ftp.mkd(i)
upload_dir(ftp, i, new_local_path);
except Exception as e:
print("文件夹上传失败:" + get_dir_name(i))
print("失败原因:" + e)

# 退出当前目录
ftp.cwd("..")

# 设置编码,解决上传的文件包含中文的问题
ftp.encoding = 'GBK'
path = "/CaseData/nc.vo.sdp.testcase.testcase.TestcaseHVO/"
local_path = "D:/ftp上传"
upload_dir(ftp, path, local_path)

这是本地的路径。

Python操作FTP服务器实现文件和文件夹的上传与下载,python清理ftp目录下的所有文件和非空文件夹_FTP服务器_04

这里服务器路径,可以看到里面的嵌套目录也同步被上传了。

Python操作FTP服务器实现文件和文件夹的上传与下载,python清理ftp目录下的所有文件和非空文件夹_上传_05

第二章:相关问题

① 上传的文件名包含中文【‘utf-8’ codec can’t decode byte …】

设置下 ​FTP​ 对象的编码为 ​GBK​ 即可。

​​ftp.encoding = 'GBK'​​

不然会报如下错误:​​UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd7 in position 114: invalid continuation byte​​

② 指定的路径存在问题【550 The system cannot find the file specified.】

开始我用 ​​split(" ")[-1]​​ 方法截取文件名,由于有的文件含有中文,截取后的文件名称不对了。

就报了 ​​ftplib.error_perm: 550 The system cannot find the file specified.​​ 的错误。

③ 上传文件前未加STOR标识【500 Command not understood.】

上传文件时 ​FTP​ 路径前要加个 ​​'STOR '​​,不然就会报 ​500​ 错误,注意后面还跟了个空格。

# 上传文件
ftp.storbinary("STOR " + i, f)

不然就报 ​​ftplib.error_perm: 500 Command not understood.​​ 错误了。

④ 上传文件夹包含中文名【暂未解决】

目前 ​​ftp.mkd(i)​​ 方法创建文件夹时如果包含中文名时会报错,暂未找到解决方法。

喜欢的点个赞❤吧!


上一篇:查看自己生日是否在pi中【Python习题】
下一篇:没有了
网友评论