w1748 发表于 2022-11-13 23:00

python实现ftp上传目录中所有文件且结构不变

本帖最后由 w1748 于 2022-11-14 00:30 编辑

今天看见个FTP批量上传文件的需求,经过资料查找大概有了思路。首先引用所需求库,
      from ftplib import FTP
      import os, re
再设定所需的参数IP,PORT。
      self.ftp = FTP()
      self.IP = IP
      self.PORT = PORT
      self.buf_size = 1024
我们就可以开始解决问题,首先要解决的是目录结构的保存,这里可以采用os.walk()来获取
      def dir_path(self, path):
                cont = []
                for content_list in os.walk(path):
                        cont.append(content_list)
                return cont
返回出来的列表中的数据为(当前文件夹路径,文件夹,文件),就这样目录结构的数据已经得到了,接下来开始实现FTP的连接
      def start_ftp(self, user=None, pwd=None):
                self.ftp.connect(self.IP, self.PORT)
                if user is None:
                        user = ""
                        pwd = ""
                self.ftp.login(user, pwd)
                print("登录成功")
连接后就可以开始实现文件的上传问题(并没有写太多判断是否存在的代码,毕竟没写多长时间)
      def upload_file(self, local_path, net_path):
                with open(local_path, 'rb') as file:
                        self.ftp.storbinary(f'STOR {net_path}', file, self.buf_size)
                print(local_path)
这是一个最基本的上传代码,每次只能单个文件,我们现在要做的就是对代码进行改进。
已经知道了我们得到的cont里面文件结构的形式,于是我们可以利用os.path.join()这个函数来组合文件路径,那么又产生了个难点——ftp端的目录结构怎么建立。
苦思冥想之下,我想到了万能的正则表达式,使用正则表达所去掉路径中不需要的部分,再利用ftp.mkd()创建文件夹。到这里问题基本就解决了,剩下的全放在简易代码中。
      from ftplib import FTP
      import os, re

      class Ftp_th:
                def __init__(self, IP, PORT):
                        self.ftp = FTP()
                        self.IP = IP
                        self.PORT = PORT
                        self.buf_size = 1024

                def dir_path(self, path):
                        cont = []
                        for content_list in os.walk(path):
                              cont.append(content_list)
                        return cont

                def start_ftp(self, user=None, pwd=None):
                        self.ftp.connect(self.IP, self.PORT)
                        if user is None:
                              user = ""
                              pwd = ""
                        self.ftp.login(user, pwd)
                        print("登录成功")

                def upload_file(self, local_path, net_path):
                        with open(local_path, 'rb') as file:
                              self.ftp.storbinary(f'STOR {net_path}', file, self.buf_size)
                        print(local_path)

                def th_upload_file(self, local_path, net_path, cont):
                        for items in cont:
                              if items == None: pass
                              else:
                                        for item_1 in items:
                                                path_1 = re.findall(r'(?<={}/).*'.format(local_path), os.path.join(items, item_1))
                                                print(path_1)
                                                with open(os.path.join(items, item_1), 'rb') as file:
                                                      self.ftp.storbinary(f'STOR {path_1}', file, self.buf_size)
                              if items == None: pass
                              else:
                                        for item_2 in items:
                                                print(item_2)
                                                path_2 = re.findall(r'(?<={}).*'.format(local_path), os.path.join(local_path, item_2))
                                                print(path_2)
                                                self.ftp.mkd(path_2)

vfa 发表于 2022-11-14 11:14

接下来建议完善一下程序功能:记录上传日志的模块、上传后校对文件大小、删除已上传的本地文件和空目录、重复文件不再上传等等,哈哈。

zxf98 发表于 2022-11-14 11:43

能不能出个sftp版的:lol

libaogui2022 发表于 2022-11-14 21:31

python实现ftp讲的很好,现在为了安全,大家要用sftp来保证数据安全。

PLAQD 发表于 2022-11-15 07:44


谢谢楼主,已收藏
页: [1]
查看完整版本: python实现ftp上传目录中所有文件且结构不变