• Python实现FTP服务功能


    Python实现FTP服务功能

     

    本文从以下三个方面, 阐述Python如何搭建FTP服务器

    一. Python搭建FTP服务器

    二. FTP函数释义

    三. 查看目录结构

    四. 上传下载程序

    一. Python搭建FTP服务器

    1. 搭建FTP服务器的Server端

    复制代码
    # -*- coding:utf-8 -*-
    from pyftpdlib.authorizers import DummyAuthorizer
    from  pyftpdlib.handlers  import FTPHandler
    from  pyftpdlib.servers import FTPServer
    # 实例化DummyAuthorizer来创建ftp用户
    authorizer = DummyAuthorizer()
    # 参数:用户名,密码,目录,权限
    authorizer.add_user('admin', '123456', r'C:UsersAdministratorDesktopftp', perm='elradfmwMT')
    # 匿名登录
    # authorizer.add_anonymous('/home/nobody')
    handler = FTPHandler
    handler.authorizer = authorizer
    # 参数:IP,端口,handler
    server = FTPServer(('0.0.0.0', 2121), handler)           #设置为0.0.0.0为本机的IP地址
    server.serve_forever()
    复制代码

    2. FTP服务器的客户端连接

    复制代码
    # -*- coding: utf-8 -*-
    from ftplib import FTP
    import time,tarfile,os
    
    
    #连接ftp
    def ftpconnect(host,port, username, password):
        ftp = FTP()
        # 打开调试级别2,显示详细信息
        # ftp.set_debuglevel(2)
        ftp.connect(host, port)
        ftp.login(username, password)
        return ftp
    
    #从ftp下载文件
    def downloadfile(ftp, remotepath, localpath):
        # 设置的缓冲区大小
        bufsize = 1024
        fp = open(localpath, 'wb')
        ftp.retrbinary('RETR ' + remotepath, fp.write, bufsize)
        ftp.set_debuglevel(0)# 参数为0,关闭调试模式
        fp.close()
    
    #从本地上传文件到ftp
    def uploadfile(ftp, remotepath, localpath):
        bufsize = 1024
        fp = open(localpath, 'rb')
        ftp.storbinary('STOR ' + remotepath, fp, bufsize)
        ftp.set_debuglevel(0)
        fp.close()
    
    if __name__ == "__main__":
        #host,port, username, password
        ftp = ftpconnect("192.168.10.113", 2121,"admin", "123456")
        #下载文件,第一个是ftp服务器路径下的文件,第二个是要下载到本地的路径文件
        downloadfile(ftp, "/12.mp3", r"C:UsersAdministratorDesktopftpdownload	est.mp3")
        # 上传文件,第一个是要上传到ftp服务器路径下的文件,第二个是本地要上传的的路径文件
        uploadfile(ftp, '/upload/1.txt', "C:/Users/Administrator/Desktop/1.txt")
        # ftp.close() #关闭ftp
        # #调用本地播放器播放下载的视频
        # os.system('start D:softkugouKGMusicKuGou.exe C:UsersAdministratorDesktopftp	est.mp3')
    
        print(ftp.getwelcome())# 打印出欢迎信息
        # 获取当前路径
        pwd_path = ftp.pwd()
        print("FTP当前路径:", pwd_path)
        # 显示目录下所有目录信息
        # ftp.dir()
        # 设置FTP当前操作的路径
        ftp.cwd('/upload/')
        # 返回一个文件名列表
        filename_list = ftp.nlst()
        print(filename_list)
    
        ftp.mkd('目录名')# 新建远程目录
        ftp.rmd('目录名')  # 删除远程目录
        ftp.delete('文件名')  # 删除远程文件
        ftp.rename('fromname', 'toname')  # 将fromname修改名称为toname
    
        # 逐行读取ftp文本文件
        file = '/upload/1.txt'
        # ftp.retrlines('RETR %s' % file)
        #与 retrlines()类似,只是这个指令处理二进制文件。回调函数 cb 用于处理每一块(块大小默认为 8KB)下载的数据
        # ftp.retrbinary('RETR %s' % file) 
    复制代码

    二. FTP函数释义

    Python中默认安装的ftplib模块定义了FTP类,其中函数有限,可用来实现简单的ftp客户端,用于上传或下载文件,函数列举如下

    复制代码
    ftp登陆连接
    from ftplib import FTP            #加载ftp模块
    ftp=FTP()                         #设置变量
    ftp.set_debuglevel(2)             #打开调试级别2,显示详细信息
    ftp.connect("IP","port")          #连接的ftp sever和端口
    ftp.login("user","password")      #连接的用户名,密码
    print ftp.getwelcome()            #打印出欢迎信息
    ftp.cmd("xxx/xxx")                #进入远程目录
    bufsize=1024                      #设置的缓冲区大小
    filename="filename.txt"           #需要下载的文件
    file_handle=open(filename,"wb").write #以写模式在本地打开文件
    ftp.retrbinaly("RETR filename.txt",file_handle,bufsize) #接收服务器上文件并写入本地文件
    ftp.set_debuglevel(0)             #关闭调试模式
    ftp.quit()                        #退出ftp
    
    ftp相关命令操作
    ftp.cwd(pathname)                 #设置FTP当前操作的路径
    ftp.dir()                         #显示目录下所有目录信息
    ftp.nlst()                        #获取目录下的文件
    ftp.mkd(pathname)                 #新建远程目录
    ftp.pwd()                         #返回当前所在位置
    ftp.rmd(dirname)                  #删除远程目录
    ftp.delete(filename)              #删除远程文件
    ftp.rename(fromname, toname)#将fromname修改名称为toname。
    ftp.storbinaly("STOR filename.txt",file_handel,bufsize)  #上传目标文件
    ftp.retrbinary("RETR filename.txt",file_handel,bufsize)  #下载FTP文件
    复制代码

    FTP.quit()与FTP.close()的区别

    FTP.quit():发送QUIT命令给服务器并关闭掉连接。这是一个比较“缓和”的关闭连接方式,但是如果服务器对QUIT命令返回错误时,会抛出异常。

    FTP.close():单方面的关闭掉连接,不应该用在已经关闭的连接之后,例如不应用在FTP.quit()之后。

    复制代码
    FTP对象方法说明
    
    login(user=’anonymous’,passwd=”, acct=”) 登录 FTP 服务器,所有参数都是可选的
    pwd() 获得当前工作目录
    cwd(path) 把当前工作目录设置为 path 所示的路径
    dir ([path[,…[,cb]]) 显示 path 目录里的内容,可选的参数 cb 是一个回调函数,会传递给 retrlines()方法
    nlst ([path[,…]) 与 dir()类似, 但返回一个文件名列表,而不是显示这些文件名
    retrlines(cmd [, cb]) 给定 FTP命令(如“ RETR filename”),用于下载文本文件。可选的回调函数 cb 用于处理文件的每一行
    retrbinary(cmd,cb[,bs=8192[, ra]]) 与 retrlines()类似,只是这个指令处理二进制文件。回调函数 cb 用于处理每一块(块大小默认为 8KB)下载的数据
    storlines(cmd, f) 给定 FTP 命令(如“ STOR filename”),用来上传文本文件。要给定一个文件对象 f
    storbinary(cmd, f,[,bs=8192]) 与 storlines()类似,只是这个指令处理二进制文件。要给定一个文件对象 f,上传块大小 bs 默认为 8KB
    rename(old, new) 把远程文件 old 重命名为 new
    delete(path) 删除位于 path 的远程文件
    mkd(directory) 创建远程目录
    rmd(directory) 删除远程目录
    quit() 关闭连接并退出
    复制代码

    三. 查看目录结构

    ftp.dir() 能显示目录下的文件信息,考虑到要分别对文件夹个数和文件数目进行统计,文件夹下存在文件夹和文件嵌套;将dir()后的目录信息放入列表,对列表进行操作;进入子文件夹后进行递归调用操作。

    复制代码
    # -*- coding: utf-8 -*-
     
    from ftplib import FTP
     
    ftp = FTP()
    ftp.connect('132.121.xx.xxx', 'xx909')
    ftp.login('crmyun_xxx', 'wyjjjjxJ')
    sum1 = 0
    sum2 = 0
    value = 0
     
    def search_file(start_dir):
     ftp.cwd(start_dir)
     print ftp.pwd()
     dir_res = []
     ftp.dir('.', dir_res.append) #对当前目录进行dir(),将结果放入列表
     for i in dir_res:
      if i.startswith("d"):
       global sum1 
       sum1 += 1
       search_file(ftp.pwd()+"/"+i.split(" ")[-1])
       ftp.cwd('..')
      else:
       global sum2, value
       sum2 += 1
       val = i.split(" ")[-1]
       value += ftp.size(val)
       if ftp.pwd().endswith('/'):    
    #    print ftp.pwd()+val+"  "+str(ftp.size(val))+" B" #打印出每个文件路径和大小
        pass
       else:    
    #    print ftp.pwd()+"/"+val+"  "+str(ftp.size(val))+" B"
        pass
    def sum_file(file_path):
     search_file(file_path)
     print "folder number is "+str(sum1)+", file number is "+str(sum2)+", Totle size is "+str(value)+" B"
      
     
    if __name__ == '__main__':
     sum_file("/apps/crmyun/crmyun_755")
    复制代码

    展示结果:

    四. 上传下载程序

    完整上传程序

    Python中默认安装的ftplib模块定义了FTP类,其中函数有限,可用来实现简单的ftp客户端,用于上传或下载文件

    复制代码
    # coding: utf-8
    from ftplib import FTP
    import time
    import tarfile
    import os
    # !/usr/bin/python
    # -*- coding: utf-8 -*-
     
    from ftplib import FTP
     
    def ftpconnect(host, username, password):
     ftp = FTP()
     # ftp.set_debuglevel(2)
     ftp.connect(host, 21)
     ftp.login(username, password)
     return ftp
     
    #从ftp下载文件
    def downloadfile(ftp, remotepath, localpath):
     bufsize = 1024
     fp = open(localpath, 'wb')
     ftp.retrbinary('RETR ' + remotepath, fp.write, bufsize)
     ftp.set_debuglevel(0)
     fp.close()
     
    #从本地上传文件到ftp
    def uploadfile(ftp, remotepath, localpath):
     bufsize = 1024
     fp = open(localpath, 'rb')
     ftp.storbinary('STOR ' + remotepath, fp, bufsize)
     ftp.set_debuglevel(0)
     fp.close()
     
    if __name__ == "__main__":
     ftp = ftpconnect("113.105.139.xxx", "ftp***", "Guest***")
     downloadfile(ftp, "Faint.mp4", "C:/Users/Administrator/Desktop/test.mp4")
     #调用本地播放器播放下载的视频
     os.system('start "C:Program FilesWindows Media Playerwmplayer.exe" "C:/Users/Administrator/Desktop/test.mp4"')
     uploadfile(ftp, "C:/Users/Administrator/Desktop/test.mp4", "test.mp4")
     
     ftp.quit()
    复制代码

    server main 代码:

    复制代码
    # _*_ coding:utf-8 _*_
    import os, sys, json, hashlib, socketserver, time
     
    base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    sys.path.append(base_dir)
    from conf import userdb_set
    class Ftp_server(socketserver.BaseRequestHandler):
     user_home_dir = ''
     def auth(self, *args):
      '''验证用户名及密码'''
      cmd_dic = args[0]
      username = cmd_dic["username"]
      password = cmd_dic["password"]
      f = open(userdb_set.userdb_set(), 'r')
      user_info = json.load(f)
      if username in user_info.keys():
       if password == user_info[username]:
        self.request.send('0'.encode())
        os.chdir('/home/%s' % username)
        self.user_home_dir = os.popen('pwd').read().strip()
        data = "%s login successed" % username
        self.loging(data)
       else:
        self.request.send('1'.encode())
        data = "%s login failed" % username
        self.loging(data)
        f.close
      else:
       self.request.send('1'.encode())
       data = "%s login failed" % username
       self.loging(data)
       f.close
       ##########################################
     
     def get(self, *args):
      '''给客户端传输文件'''
      request_code = {
       '0': 'file is ready to get',
       '1': 'file not found!'
      }
      cmd_dic = args[0]
      self.loging(json.dumps(cmd_dic))
      filename = cmd_dic["filename"]
      if os.path.isfile(filename):
       self.request.send('0'.encode('utf-8')) # 确认文件存在
       self.request.recv(1024)
       self.request.send(str(os.stat(filename).st_size).encode('utf-8'))
       self.request.recv(1024)
       m = hashlib.md5()
       f = open(filename, 'rb')
       for line in f:
        m.update(line)
        self.request.send(line)
       self.request.send(m.hexdigest().encode('utf-8'))
       print('From server:Md5 value has been sended!')
       f.close()
      else:
       self.request.send('1'.encode('utf-8'))
       ###########################################
     
     def cd(self, *args):
      '''执行cd命令'''
      user_current_dir = os.popen('pwd').read().strip()
      cmd_dic = args[0]
      self.loging(json.dumps(cmd_dic))
      path = cmd_dic['path']
      if path.startswith('/'):
       if self.user_home_dir in path:
        os.chdir(path)
        new_dir = os.popen('pwd').read()
        user_current_dir = new_dir
        self.request.send('Change dir successfully!'.encode("utf-8"))
        data = 'Change dir successfully!'
        self.loging(data)
       elif os.path.exists(path):
        self.request.send('Permission Denied!'.encode("utf-8"))
        data = 'Permission Denied!'
        self.loging(data)
       else:
        self.request.send('Directory not found!'.encode("utf-8"))
        data = 'Directory not found!'
        self.loging(data)
      elif os.path.exists(path):
       os.chdir(path)
       new_dir = os.popen('pwd').read().strip()
       if self.user_home_dir in new_dir:
        self.request.send('Change dir successfully!'.encode("utf-8"))
        user_current_dir = new_dir
        data = 'Change dir successfully!'
        self.loging(data)
       else:
        os.chdir(user_current_dir)
        self.request.send('Permission Denied!'.encode("utf-8"))
        data = 'Permission Denied!'
        self.loging(data)
      else:
       self.request.send('Directory not found!'.encode("utf-8"))
       data = 'Directory not found!'
       self.loging(data)
       ###########################################
     
     def rm(self, *args):
      request_code = {
       '0': 'file exist,and Please confirm whether to rm',
       '1': 'file not found!'
      }
      cmd_dic = args[0]
      self.loging(json.dumps(cmd_dic))
      filename = cmd_dic['filename']
      if os.path.exists(filename):
       self.request.send('0'.encode("utf-8")) # 确认文件存在
       client_response = self.request.recv(1024).decode()
       if client_response == '0':
        os.popen('rm -rf %s' % filename)
        self.request.send(('File %s has been deleted!' % filename).encode("utf-8"))
        self.loging('File %s has been deleted!' % filename)
       else:
        self.request.send(('File %s not deleted!' % filename).encode("utf-8"))
        self.loging('File %s not deleted!' % filename)
      else:
       self.request.send('1'.encode("utf-8"))
       ########################################
     
     def pwd(self, *args):
      '''执行pwd命令'''
      cmd_dic = args[0]
      self.loging(json.dumps(cmd_dic))
      server_response = os.popen('pwd').read().strip().encode("utf-8")
      self.request.send(server_response)
     
     #############################################
     def ls(self, *args):
      '''执行ls命名'''
      cmd_dic = args[0]
      self.loging(json.dumps(cmd_dic))
      path = cmd_dic['path']
      cmd = 'ls -l %s' % path
      server_response = os.popen(cmd).read().encode("utf-8")
      self.request.send(server_response)
     
     ############################################
     def put(self, *args):
      '''接收客户端文件'''
      cmd_dic = args[0]
      self.loging(json.dumps(cmd_dic))
      filename = cmd_dic["filename"]
      filesize = cmd_dic["size"]
      if os.path.isfile(filename):
       f = open(filename + '.new', 'wb')
      else:
       f = open(filename, 'wb')
      request_code = {
       '200': 'Ready to recceive data!',
       '210': 'Not ready to received data!'
      }
      self.request.send('200'.encode())
      receive_size = 0
      while True:
       if receive_size < filesize:
        data = self.request.recv(1024)
        f.write(data)
        receive_size += len(data)
       else:
        data = "File %s has been uploaded successfully!" % filename
        self.loging(data)
        print(data)
        break
     
        ################################################
     
     def mkdir(self, *args):
      request_code = {
       '0': 'Directory has been made!',
       '1': 'Directory is aleady exist!'
      }
      cmd_dic = args[0]
      self.loging(json.dumps(cmd_dic))
      dir_name = cmd_dic['dir_name']
      if os.path.exists(dir_name):
       self.request.send('1'.encode("utf-8"))
      else:
       os.popen('mkdir %s' % dir_name)
       self.request.send('0'.encode("utf-8"))
     
       #############################################
     
      def loging(self, data):
      '''日志记录'''
      localtime = time.asctime(time.localtime(time.time()))
      log_file = '/root/ftp/ftpserver/log/server.log'
      with open(log_file, 'a', encoding='utf-8') as f:
       f.write('%s-->' % localtime + data + '
    ')
       ##############################################
     
     def handle(self):
      # print("您本次访问使用的IP为:%s" %self.client_address[0])
      # localtime = time.asctime( time.localtime(time.time()))
      # print(localtime)
     
      while True:
       try:
        self.data = self.request.recv(1024).decode() #
        # print(self.data)
        cmd_dic = json.loads(self.data)
        action = cmd_dic["action"]
        # print("用户请求%s"%action)
        if hasattr(self, action):
         func = getattr(self, action)
         func(cmd_dic)
       except Exception as e:
        self.loging(str(e))
        break
     
    def run():
     HOST, PORT = '0.0.0.0', 6969
     print("The server is started,and listenning at port 6969")
     server = socketserver.ThreadingTCPServer((HOST, PORT), Ftp_server)
     server.serve_forever()
    if __name__ == '__main__':
     run()
    复制代码

    设置用户口令代码:

    复制代码
    #_*_ coding:utf-8 _*_
    import os,json,hashlib,sys
     
    base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    userdb_file = base_dir+"data\userdb"
    # print(userdb_file)
    def userdb_set():
     if os.path.isfile(userdb_file):
      # print(userdb_file)
      return userdb_file
     else:
      print('请先为您的服务器创建用户!')
      user_data = {}
      dict={}
      Exit_flags = True
      while Exit_flags:
       username = input("Please input username:")
       if username != 'exit':
        password = input("Please input passwod:")
        if password != 'exit':
          user_data.update({username:password})
          m = hashlib.md5()
          # m.update('hello')
          # print(m.hexdigest())
          for i in user_data:
           # print(i,user_data[i])
           m.update(user_data[i].encode())
           dict.update({i:m.hexdigest()})
        else:
         break
       else:
        break
      f = open(userdb_file,'w')
      json.dump(dict,f)
      f.close()
     return userdb_file
    复制代码

    带进度条下载文件

      1 from ftplib import FTP
      2 from ftplib import error_perm
      3 import os
      4 import socket
      5 import os
      6 import time
      7 from utils import my_logset
      8 from utils.time_utils import run_time
      9 import sys
     10 import math
     11 from utils import file_util
     12 
     13 """
     14 ftp操作上传和下载
     15 """
     16 
     17 
     18 class FTP_OPS(object):
     19     """
     20     ftp文件操作
     21     """
     22 
     23     def __init__(self, log_file, ftp_ip, ftp_port, ftp_user, ftp_pwd):
     24         self.db_log = my_logset.get_mylogger("ftp", log_file)
     25         self.ftp_ip = ftp_ip
     26         self.ftp_port = ftp_port
     27         self.ftp_user = ftp_user
     28         self.ftp_pwd = ftp_pwd
     29 
     30     def ftp_connect(self):
     31         """
     32         连接ftp
     33         :return:
     34         """
     35         socket.setdefaulttimeout(160)  # 超时FTP时间设置为60秒
     36         ftp = FTP()
     37         ftp.connect(host=self.ftp_ip, port=self.ftp_port)
     38         ftp.set_debuglevel(2)  # 开启调试模式
     39         ftp.encoding = 'utf-8'
     40 
     41         try:
     42             ftp.login(self.ftp_user, self.ftp_pwd)
     43             self.db_log.info(
     44                 '[{}]login ftp {}'.format(
     45                     self.ftp_user,
     46                     ftp.getwelcome()))  # 打印欢迎信息
     47 
     48         except(socket.error, socket.gaierror):  # ftp 连接错误
     49             self.db_log.warn(
     50                 "ERROR: cannot connect [{}:{}]".format(
     51                     self.ftp_ip, self.ftp_port))
     52             return None
     53 
     54         except error_perm:  # 用户登录认证错误
     55             self.db_log.warn("ERROR: user Authentication failed ")
     56             return None
     57         except Exception as e:
     58             print(e)
     59             return None
     60         return ftp
     61 
     62     @run_time
     63     def upload_file(self, ftp: FTP, remotepath: str,
     64                     localpath: str, file: str):
     65         """
     66          # 从本地上传文件到ftp
     67         :param ftp: ftp对象
     68         :param remotepath: ftp远程路径
     69         :param localpath: 本地
     70         :return:
     71         """
     72         flag = False
     73         buffer_size = 10240  # 默认是8192
     74         print(ftp.getwelcome())  # 显示登录ftp信息
     75 
     76         fp = open(os.path.join(localpath, file), 'rb')
     77 
     78         try:
     79             ftp.cwd(remotepath)  # 进入远程目录
     80             self.db_log.info(
     81                 "found folder [{}] in ftp server, upload processing.".format(remotepath))
     82             print('进入目录', ftp.pwd())
     83             # 将传输模式改为二进制模式 ,避免提示 ftplib.error_perm: 550 SIZE not allowed in
     84             # ASCII
     85             ftp.voidcmd('TYPE I')
     86             ftp.storbinary('STOR ' + file, fp, buffer_size)
     87             ftp.set_debuglevel(0)
     88             self.db_log.info("上传文件 [{}] 成功".format(file))
     89             flag = True
     90         except error_perm as e:
     91             self.db_log.warn('文件[{}]传输有误,{}'.format(file, str(e)))
     92         except TimeoutError:
     93             self.db_log.warn('文件[{}]传输超时'.format(file))
     94             pass
     95         except Exception as e:
     96             self.db_log.warn('文件[{}]传输异常'.format(file, str(e)))
     97             pass
     98         finally:
     99             fp.close()
    100 
    101         return {'file_name': file, 'flag': flag}
    102 
    103     def download_file(self, ftp_file_path, dst_file_path):
    104         """
    105         从ftp下载文件到本地
    106         :param ftp_file_path: ftp下载文件
    107         :param dst_file_path: 本地存放
    108         :return:
    109         """
    110         buffer_size = 10240  # 默认是8192
    111         ftp = self.ftp_connect()
    112         print(ftp.getwelcome())  # 显示登录ftp信息
    113 
    114         # 将传输模式改为二进制模式 ,避免提示 ftplib.error_perm: 550 SIZE not allowed in ASCII
    115         ftp.voidcmd('TYPE I')
    116         remote_file_size = ftp.size(ftp_file_path)  # 文件总大小
    117 
    118         print('remote filesize [{}]'.format(remote_file_size))
    119         cmpsize = 0  # 下载文件初始大小
    120         lsize = 0
    121         # check local file isn't exists and get the local file size
    122         if os.path.exists(dst_file_path):
    123             lsize = os.stat(dst_file_path).st_size
    124         if lsize >= remote_file_size:
    125             print('local file is bigger or equal remote file')
    126             return
    127         start = time.time()
    128         conn = ftp.transfercmd('RETR {0}'.format(ftp_file_path), lsize)
    129 
    130         f = open(dst_file_path, "ab")
    131         while True:
    132             data = conn.recv(buffer_size)
    133             if not data:
    134                 break
    135             f.write(data)
    136             cmpsize += len(data)
    137             self.progressbar(cmpsize, remote_file_size)
    138             # print(
    139             #      ''*30, 'download process:%.2f%%' %
    140             #     (float(cmpsize) / remote_file_size * 100))
    141             # ftp.retrbinary(
    142             #     'RETR {0}'.format(ftp_file_path),
    143             #     f.write,
    144             #     buffer_size)
    145         f.close()
    146         try:
    147             ftp.voidcmd('NOOP')
    148             print('keep alive cmd success')
    149             ftp.voidresp()
    150             print('No loop cmd')
    151             conn.close()
    152             ftp.quit()
    153         except Exception as e:
    154             pass
    155         finally:
    156             end = time.time()
    157             print('consume time [{}]'.format(end - start))
    158             file_size = os.stat(dst_file_path).st_size
    159             print('local filesize [{}] md5:[{}]'.format(
    160                 file_size, file_util.get_md5(dst_file_path)))
    161 
    162         def progressbar(cur, total):
    163             """
    164               进度条显示
    165               cur表示当前的数值,total表示总的数值。
    166             :param cur:
    167             :param total:
    168             :return:
    169             """
    170             percent = '{:.2%}'.format(cur / total)
    171             sys.stdout.write('
    ')
    172             sys.stdout.write('[%-50s] %s' %
    173                              ('=' * int(math.floor(cur * 50 / total)), percent))
    174             sys.stdout.flush()
    175             if cur == total:
    176                 sys.stdout.write('
    ')
    177 
    178 
    179 if __name__ == '__main__':
    180     host = "10.0.0.1"
    181     username = "test"
    182     password = "test"
    183     port = "21"
    184     ftp_file_path = "/data/an/1.zip"
    185     dst_file_path = "/data/tmp/1.zip"
    186     ftp = FTP_OPS(host=host, username=username, password=password, port=port)
    187     ftp.download_file(ftp_file_path=ftp_file_path, dst_file_path=dst_file_path)

    参考文章:

    python的ftplib包介绍:https://docs.python.org/3/library/ftplib.html
    https://blog.csdn.net/xc_zhou/article/details/81021414
    https://www.jb51.net/article/142388.htm
    https://www.jb51.net/article/109429.htm
    https://www.cnblogs.com/hltswd/p/6228992.html

  • 相关阅读:
    oracle对象之序列
    PLSql工具介绍
    oracle对象之同义词
    oracle对象之视图
    缓存问题汇总
    消息队列问题汇总
    算法-排序算法-1
    redis-主从数据一致
    数据结构与算法-完全二叉树/满二叉树
    写缓冲器与无效化队列
  • 原文地址:https://www.cnblogs.com/mikew/p/13215765.html
Copyright © 2020-2023  润新知