【无标题】

欢迎使用Markdown编辑器

你好! 这是你第一次使用







一、背景

最近公司的一些自动化操作需要使用Python来实现FTP的上传和下载功能。因此参考网上的例子,撸了一段代码来实现了该功能,下面做个记录。

二、ftplib介绍

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

  • Python 2.7系列官方文档: https://docs.python.org/2/library/ftplib.html
  • Python 3.5系列官方文档:https://docs.python.org/3.5/library/ftplib.html
  • Python 3.6系列官方文档:https://docs.python.org/3.6/library/ftplib.html

ftplib中的FTP 主要有以下这些方法
这里写图片描述

这里写图片描述

这些方法,可以参考源代码,也可以参考上面贴的官方文档来进行学习。

这里写图片描述

这里写图片描述

这里写图片描述

我们主要需要使用到的api有以下几个:

  • 1、连接服务器:
ftp=FTP()                   #设置变量

ftp.connect(“IP”,“port”) #连接的ftp sever和端口

ftp.login(“user”,“password”)#连接的用户名,密码如果匿名登录则用空串代替即可

  • 1
  • 2
  • 3
  • 4
  • 5
  • 2、上传文件:
fp=open('E:/test.xlsx','rb')      

cmd=‘STOR filepath/test.xlsx’

ftp.storbinary(cmd, fp)

  • 1
  • 2
  • 3
  • 4
  • 5

storbinary是以二进制形式上传文件。
cmd: STOR命令,是FTP的一个命令,后面需要加上保存文件的路径及文件名
fp: 一个打开的文件对象,‘rb’,以二进制形式打开文件

  • 3、下载文件:
ftp.nlst(path) #获取目录下的文件

file_handle=open(filename,“wb”).write #以写模式在本地打开文件

ftp.retrbinary(“RETR filename.txt”,file_handle) #接收服务器上文件并写入本地文件

  • 1
  • 2
  • 3
  • 4
  • 5
  • 4、其他方法:
ftp.set_debuglevel(2)       #打开调试级别2,显示详细信息

ftp.set_pasv(0) #0主动模式 1 #被动模式

print ftp.getwelcome() #打印出欢迎信息

ftp.cmd(“xxx/xxx”) #更改远程目录

ftp.set_debuglevel(0) #关闭调试模式

ftp.quit() #退出ftp

ftp.dir() #显示目录下文件信息

ftp.mkd(pathname) #新建远程目录

ftp.pwd() #返回当前所在位置

ftp.rmd(dirname) #删除远程目录

ftp.delete(filename) #删除远程文件

ftp.rename(fromname, toname) #将fromname修改名称为toname。

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

三、使用ftplib来实现FTP上传下载功能

参考官网以及互联网其他资源,撸了下面这份代码,作为一个FTP工具类

#!/usr/bin/python
# -*- coding: UTF-8 -*-

from ftplib import FTP
import os
import sys
import time
import socket

class MyFTP:
“”"
ftp自动下载、自动上传脚本,可以递归目录操作
作者:欧阳鹏
博客地址:http://blog.csdn.net/ouyang_peng/article/details/79271113
“”"

<span class="token keyword">def</span> <span class="token function">__init__</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span> host<span class="token punctuation">,</span> port<span class="token operator">=</span><span class="token number">21</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token triple-quoted-string string">""" 初始化 FTP 客户端
    参数:
             host:ip地址

             port:端口号
    """</span>
    <span class="token comment"># print("__init__()---&gt; host = %s ,port = %s" % (host, port))</span>

    self<span class="token punctuation">.</span>host <span class="token operator">=</span> host
    self<span class="token punctuation">.</span>port <span class="token operator">=</span> port
    self<span class="token punctuation">.</span>ftp <span class="token operator">=</span> FTP<span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token comment"># 重新设置下编码方式</span>
    self<span class="token punctuation">.</span>ftp<span class="token punctuation">.</span>encoding <span class="token operator">=</span> <span class="token string">'gbk'</span>
    self<span class="token punctuation">.</span>log_file <span class="token operator">=</span> <span class="token builtin">open</span><span class="token punctuation">(</span><span class="token string">"log.txt"</span><span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">)</span>
    self<span class="token punctuation">.</span>file_list <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>

<span class="token keyword">def</span> <span class="token function">login</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span> username<span class="token punctuation">,</span> password<span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token triple-quoted-string string">""" 初始化 FTP 客户端
        参数:
              username: 用户名

             password: 密码
        """</span>
    <span class="token keyword">try</span><span class="token punctuation">:</span>
        timeout <span class="token operator">=</span> <span class="token number">60</span>
        socket<span class="token punctuation">.</span>setdefaulttimeout<span class="token punctuation">(</span>timeout<span class="token punctuation">)</span>
        <span class="token comment"># 0主动模式 1 #被动模式</span>
        self<span class="token punctuation">.</span>ftp<span class="token punctuation">.</span>set_pasv<span class="token punctuation">(</span><span class="token boolean">True</span><span class="token punctuation">)</span>
        <span class="token comment"># 打开调试级别2,显示详细信息</span>
        <span class="token comment"># self.ftp.set_debuglevel(2)</span>

        self<span class="token punctuation">.</span>debug_print<span class="token punctuation">(</span><span class="token string">'开始尝试连接到 %s'</span> <span class="token operator">%</span> self<span class="token punctuation">.</span>host<span class="token punctuation">)</span>
        self<span class="token punctuation">.</span>ftp<span class="token punctuation">.</span>connect<span class="token punctuation">(</span>self<span class="token punctuation">.</span>host<span class="token punctuation">,</span> self<span class="token punctuation">.</span>port<span class="token punctuation">)</span>
        self<span class="token punctuation">.</span>debug_print<span class="token punctuation">(</span><span class="token string">'成功连接到 %s'</span> <span class="token operator">%</span> self<span class="token punctuation">.</span>host<span class="token punctuation">)</span>

        self<span class="token punctuation">.</span>debug_print<span class="token punctuation">(</span><span class="token string">'开始尝试登录到 %s'</span> <span class="token operator">%</span> self<span class="token punctuation">.</span>host<span class="token punctuation">)</span>
        self<span class="token punctuation">.</span>ftp<span class="token punctuation">.</span>login<span class="token punctuation">(</span>username<span class="token punctuation">,</span> password<span class="token punctuation">)</span>
        self<span class="token punctuation">.</span>debug_print<span class="token punctuation">(</span><span class="token string">'成功登录到 %s'</span> <span class="token operator">%</span> self<span class="token punctuation">.</span>host<span class="token punctuation">)</span>

        self<span class="token punctuation">.</span>debug_print<span class="token punctuation">(</span>self<span class="token punctuation">.</span>ftp<span class="token punctuation">.</span>welcome<span class="token punctuation">)</span>
    <span class="token keyword">except</span> Exception <span class="token keyword">as</span> err<span class="token punctuation">:</span>
        self<span class="token punctuation">.</span>deal_error<span class="token punctuation">(</span><span class="token string">"FTP 连接或登录失败 ,错误描述为:%s"</span> <span class="token operator">%</span> err<span class="token punctuation">)</span>
        <span class="token keyword">pass</span>

<span class="token keyword">def</span> <span class="token function">is_same_size</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span> local_file<span class="token punctuation">,</span> remote_file<span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token triple-quoted-string string">"""判断远程文件和本地文件大小是否一致

       参数:
         local_file: 本地文件

         remote_file: 远程文件
    """</span>
    <span class="token keyword">try</span><span class="token punctuation">:</span>
        remote_file_size <span class="token operator">=</span> self<span class="token punctuation">.</span>ftp<span class="token punctuation">.</span>size<span class="token punctuation">(</span>remote_file<span class="token punctuation">)</span>
    <span class="token keyword">except</span> Exception <span class="token keyword">as</span> err<span class="token punctuation">:</span>
        <span class="token comment"># self.debug_print("is_same_size() 错误描述为:%s" % err)</span>
        remote_file_size <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span>

    <span class="token keyword">try</span><span class="token punctuation">:</span>
        local_file_size <span class="token operator">=</span> os<span class="token punctuation">.</span>path<span class="token punctuation">.</span>getsize<span class="token punctuation">(</span>local_file<span class="token punctuation">)</span>
    <span class="token keyword">except</span> Exception <span class="token keyword">as</span> err<span class="token punctuation">:</span>
        <span class="token comment"># self.debug_print("is_same_size() 错误描述为:%s" % err)</span>
        local_file_size <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span>

    self<span class="token punctuation">.</span>debug_print<span class="token punctuation">(</span><span class="token string">'local_file_size:%d  , remote_file_size:%d'</span> <span class="token operator">%</span> <span class="token punctuation">(</span>local_file_size<span class="token punctuation">,</span> remote_file_size<span class="token punctuation">)</span><span class="token punctuation">)</span>
    <span class="token keyword">if</span> remote_file_size <span class="token operator">==</span> local_file_size<span class="token punctuation">:</span>
        <span class="token keyword">return</span> <span class="token number">1</span>
    <span class="token keyword">else</span><span class="token punctuation">:</span>
        <span class="token keyword">return</span> <span class="token number">0</span>

<span class="token keyword">def</span> <span class="token function">download_file</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span> local_file<span class="token punctuation">,</span> remote_file<span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token triple-quoted-string string">"""从ftp下载文件
        参数:
            local_file: 本地文件

            remote_file: 远程文件
    """</span>
    self<span class="token punctuation">.</span>debug_print<span class="token punctuation">(</span><span class="token string">"download_file()---&gt; local_path = %s ,remote_path = %s"</span> <span class="token operator">%</span> <span class="token punctuation">(</span>local_file<span class="token punctuation">,</span> remote_file<span class="token punctuation">)</span><span class="token punctuation">)</span>

    <span class="token keyword">if</span> self<span class="token punctuation">.</span>is_same_size<span class="token punctuation">(</span>local_file<span class="token punctuation">,</span> remote_file<span class="token punctuation">)</span><span class="token punctuation">:</span>
        self<span class="token punctuation">.</span>debug_print<span class="token punctuation">(</span><span class="token string">'%s 文件大小相同,无需下载'</span> <span class="token operator">%</span> local_file<span class="token punctuation">)</span>
        <span class="token keyword">return</span>
    <span class="token keyword">else</span><span class="token punctuation">:</span>
        <span class="token keyword">try</span><span class="token punctuation">:</span>
            self<span class="token punctuation">.</span>debug_print<span class="token punctuation">(</span><span class="token string">'&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;下载文件 %s ... ...'</span> <span class="token operator">%</span> local_file<span class="token punctuation">)</span>
            buf_size <span class="token operator">=</span> <span class="token number">1024</span>
            file_handler <span class="token operator">=</span> <span class="token builtin">open</span><span class="token punctuation">(</span>local_file<span class="token punctuation">,</span> <span class="token string">'wb'</span><span class="token punctuation">)</span>
            self<span class="token punctuation">.</span>ftp<span class="token punctuation">.</span>retrbinary<span class="token punctuation">(</span><span class="token string">'RETR %s'</span> <span class="token operator">%</span> remote_file<span class="token punctuation">,</span> file_handler<span class="token punctuation">.</span>write<span class="token punctuation">,</span> buf_size<span class="token punctuation">)</span>
            file_handler<span class="token punctuation">.</span>close<span class="token punctuation">(</span><span class="token punctuation">)</span>
        <span class="token keyword">except</span> Exception <span class="token keyword">as</span> err<span class="token punctuation">:</span>
            self<span class="token punctuation">.</span>debug_print<span class="token punctuation">(</span><span class="token string">'下载文件出错,出现异常:%s '</span> <span class="token operator">%</span> err<span class="token punctuation">)</span>
            <span class="token keyword">return</span>

<span class="token keyword">def</span> <span class="token function">download_file_tree</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span> local_path<span class="token punctuation">,</span> remote_path<span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token triple-quoted-string string">"""从远程目录下载多个文件到本地目录
                   参数:
                     local_path: 本地路径

                     remote_path: 远程路径
            """</span>
    <span class="token keyword">print</span><span class="token punctuation">(</span><span class="token string">"download_file_tree()---&gt;  local_path = %s ,remote_path = %s"</span> <span class="token operator">%</span> <span class="token punctuation">(</span>local_path<span class="token punctuation">,</span> remote_path<span class="token punctuation">)</span><span class="token punctuation">)</span>
    <span class="token keyword">try</span><span class="token punctuation">:</span>
        self<span class="token punctuation">.</span>ftp<span class="token punctuation">.</span>cwd<span class="token punctuation">(</span>remote_path<span class="token punctuation">)</span>
    <span class="token keyword">except</span> Exception <span class="token keyword">as</span> err<span class="token punctuation">:</span>
        self<span class="token punctuation">.</span>debug_print<span class="token punctuation">(</span><span class="token string">'远程目录%s不存在,继续...'</span> <span class="token operator">%</span> remote_path <span class="token operator">+</span> <span class="token string">" ,具体错误描述为:%s"</span> <span class="token operator">%</span> err<span class="token punctuation">)</span>
        <span class="token keyword">return</span>

    <span class="token keyword">if</span> <span class="token keyword">not</span> os<span class="token punctuation">.</span>path<span class="token punctuation">.</span>isdir<span class="token punctuation">(</span>local_path<span class="token punctuation">)</span><span class="token punctuation">:</span>
        self<span class="token punctuation">.</span>debug_print<span class="token punctuation">(</span><span class="token string">'本地目录%s不存在,先创建本地目录'</span> <span class="token operator">%</span> local_path<span class="token punctuation">)</span>
        os<span class="token punctuation">.</span>makedirs<span class="token punctuation">(</span>local_path<span class="token punctuation">)</span>

    self<span class="token punctuation">.</span>debug_print<span class="token punctuation">(</span><span class="token string">'切换至目录: %s'</span> <span class="token operator">%</span> self<span class="token punctuation">.</span>ftp<span class="token punctuation">.</span>pwd<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>

    self<span class="token punctuation">.</span>file_list <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
    <span class="token comment"># 方法回调</span>
    self<span class="token punctuation">.</span>ftp<span class="token punctuation">.</span><span class="token builtin">dir</span><span class="token punctuation">(</span>self<span class="token punctuation">.</span>get_file_list<span class="token punctuation">)</span>

    remote_names <span class="token operator">=</span> self<span class="token punctuation">.</span>file_list
    self<span class="token punctuation">.</span>debug_print<span class="token punctuation">(</span><span class="token string">'远程目录 列表: %s'</span> <span class="token operator">%</span> remote_names<span class="token punctuation">)</span>
    <span class="token keyword">for</span> item <span class="token keyword">in</span> remote_names<span class="token punctuation">:</span>
        file_type <span class="token operator">=</span> item<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span>
        file_name <span class="token operator">=</span> item<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span>
        local <span class="token operator">=</span> os<span class="token punctuation">.</span>path<span class="token punctuation">.</span>join<span class="token punctuation">(</span>local_path<span class="token punctuation">,</span> file_name<span class="token punctuation">)</span>
        <span class="token keyword">if</span> file_type <span class="token operator">==</span> <span class="token string">'d'</span><span class="token punctuation">:</span>
            <span class="token keyword">print</span><span class="token punctuation">(</span><span class="token string">"download_file_tree()---&gt; 下载目录: %s"</span> <span class="token operator">%</span> file_name<span class="token punctuation">)</span>
            self<span class="token punctuation">.</span>download_file_tree<span class="token punctuation">(</span>local<span class="token punctuation">,</span> file_name<span class="token punctuation">)</span>
        <span class="token keyword">elif</span> file_type <span class="token operator">==</span> <span class="token string">'-'</span><span class="token punctuation">:</span>
            <span class="token keyword">print</span><span class="token punctuation">(</span><span class="token string">"download_file()---&gt; 下载文件: %s"</span> <span class="token operator">%</span> file_name<span class="token punctuation">)</span>
            self<span class="token punctuation">.</span>download_file<span class="token punctuation">(</span>local<span class="token punctuation">,</span> file_name<span class="token punctuation">)</span>
        self<span class="token punctuation">.</span>ftp<span class="token punctuation">.</span>cwd<span class="token punctuation">(</span><span class="token string">".."</span><span class="token punctuation">)</span>
        self<span class="token punctuation">.</span>debug_print<span class="token punctuation">(</span><span class="token string">'返回上层目录 %s'</span> <span class="token operator">%</span> self<span class="token punctuation">.</span>ftp<span class="token punctuation">.</span>pwd<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
    <span class="token keyword">return</span> <span class="token boolean">True</span>

<span class="token keyword">def</span> <span class="token function">upload_file</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span> local_file<span class="token punctuation">,</span> remote_file<span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token triple-quoted-string string">"""从本地上传文件到ftp

       参数:
         local_path: 本地文件

         remote_path: 远程文件
    """</span>
    <span class="token keyword">if</span> <span class="token keyword">not</span> os<span class="token punctuation">.</span>path<span class="token punctuation">.</span>isfile<span class="token punctuation">(</span>local_file<span class="token punctuation">)</span><span class="token punctuation">:</span>
        self<span class="token punctuation">.</span>debug_print<span class="token punctuation">(</span><span class="token string">'%s 不存在'</span> <span class="token operator">%</span> local_file<span class="token punctuation">)</span>
        <span class="token keyword">return</span>

    <span class="token keyword">if</span> self<span class="token punctuation">.</span>is_same_size<span class="token punctuation">(</span>local_file<span class="token punctuation">,</span> remote_file<span class="token punctuation">)</span><span class="token punctuation">:</span>
        self<span class="token punctuation">.</span>debug_print<span class="token punctuation">(</span><span class="token string">'跳过相等的文件: %s'</span> <span class="token operator">%</span> local_file<span class="token punctuation">)</span>
        <span class="token keyword">return</span>

    buf_size <span class="token operator">=</span> <span class="token number">1024</span>
    file_handler <span class="token operator">=</span> <span class="token builtin">open</span><span class="token punctuation">(</span>local_file<span class="token punctuation">,</span> <span class="token string">'rb'</span><span class="token punctuation">)</span>
    self<span class="token punctuation">.</span>ftp<span class="token punctuation">.</span>storbinary<span class="token punctuation">(</span><span class="token string">'STOR %s'</span> <span class="token operator">%</span> remote_file<span class="token punctuation">,</span> file_handler<span class="token punctuation">,</span> buf_size<span class="token punctuation">)</span>
    file_handler<span class="token punctuation">.</span>close<span class="token punctuation">(</span><span class="token punctuation">)</span>
    self<span class="token punctuation">.</span>debug_print<span class="token punctuation">(</span><span class="token string">'上传: %s'</span> <span class="token operator">%</span> local_file <span class="token operator">+</span> <span class="token string">"成功!"</span><span class="token punctuation">)</span>

<span class="token keyword">def</span> <span class="token function">upload_file_tree</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span> local_path<span class="token punctuation">,</span> remote_path<span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token triple-quoted-string string">"""从本地上传目录下多个文件到ftp
       参数:

         local_path: 本地路径

         remote_path: 远程路径
    """</span>
    <span class="token keyword">if</span> <span class="token keyword">not</span> os<span class="token punctuation">.</span>path<span class="token punctuation">.</span>isdir<span class="token punctuation">(</span>local_path<span class="token punctuation">)</span><span class="token punctuation">:</span>
        self<span class="token punctuation">.</span>debug_print<span class="token punctuation">(</span><span class="token string">'本地目录 %s 不存在'</span> <span class="token operator">%</span> local_path<span class="token punctuation">)</span>
        <span class="token keyword">return</span>

    self<span class="token punctuation">.</span>ftp<span class="token punctuation">.</span>cwd<span class="token punctuation">(</span>remote_path<span class="token punctuation">)</span>
    self<span class="token punctuation">.</span>debug_print<span class="token punctuation">(</span><span class="token string">'切换至远程目录: %s'</span> <span class="token operator">%</span> self<span class="token punctuation">.</span>ftp<span class="token punctuation">.</span>pwd<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>

    local_name_list <span class="token operator">=</span> os<span class="token punctuation">.</span>listdir<span class="token punctuation">(</span>local_path<span class="token punctuation">)</span>
    <span class="token keyword">for</span> local_name <span class="token keyword">in</span> local_name_list<span class="token punctuation">:</span>
        src <span class="token operator">=</span> os<span class="token punctuation">.</span>path<span class="token punctuation">.</span>join<span class="token punctuation">(</span>local_path<span class="token punctuation">,</span> local_name<span class="token punctuation">)</span>
        <span class="token keyword">if</span> os<span class="token punctuation">.</span>path<span class="token punctuation">.</span>isdir<span class="token punctuation">(</span>src<span class="token punctuation">)</span><span class="token punctuation">:</span>
            <span class="token keyword">try</span><span class="token punctuation">:</span>
                self<span class="token punctuation">.</span>ftp<span class="token punctuation">.</span>mkd<span class="token punctuation">(</span>local_name<span class="token punctuation">)</span>
            <span class="token keyword">except</span> Exception <span class="token keyword">as</span> err<span class="token punctuation">:</span>
                self<span class="token punctuation">.</span>debug_print<span class="token punctuation">(</span><span class="token string">"目录已存在 %s ,具体错误描述为:%s"</span> <span class="token operator">%</span> <span class="token punctuation">(</span>local_name<span class="token punctuation">,</span> err<span class="token punctuation">)</span><span class="token punctuation">)</span>
            self<span class="token punctuation">.</span>debug_print<span class="token punctuation">(</span><span class="token string">"upload_file_tree()---&gt; 上传目录: %s"</span> <span class="token operator">%</span> local_name<span class="token punctuation">)</span>
            self<span class="token punctuation">.</span>upload_file_tree<span class="token punctuation">(</span>src<span class="token punctuation">,</span> local_name<span class="token punctuation">)</span>
        <span class="token keyword">else</span><span class="token punctuation">:</span>
            self<span class="token punctuation">.</span>debug_print<span class="token punctuation">(</span><span class="token string">"upload_file_tree()---&gt; 上传文件: %s"</span> <span class="token operator">%</span> local_name<span class="token punctuation">)</span>
            self<span class="token punctuation">.</span>upload_file<span class="token punctuation">(</span>src<span class="token punctuation">,</span> local_name<span class="token punctuation">)</span>
    self<span class="token punctuation">.</span>ftp<span class="token punctuation">.</span>cwd<span class="token punctuation">(</span><span class="token string">".."</span><span class="token punctuation">)</span>

<span class="token keyword">def</span> <span class="token function">close</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token triple-quoted-string string">""" 退出ftp
    """</span>
    self<span class="token punctuation">.</span>debug_print<span class="token punctuation">(</span><span class="token string">"close()---&gt; FTP退出"</span><span class="token punctuation">)</span>
    self<span class="token punctuation">.</span>ftp<span class="token punctuation">.</span>quit<span class="token punctuation">(</span><span class="token punctuation">)</span>
    self<span class="token punctuation">.</span>log_file<span class="token punctuation">.</span>close<span class="token punctuation">(</span><span class="token punctuation">)</span>

<span class="token keyword">def</span> <span class="token function">debug_print</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span> s<span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token triple-quoted-string string">""" 打印日志
    """</span>
    self<span class="token punctuation">.</span>write_log<span class="token punctuation">(</span>s<span class="token punctuation">)</span>

<span class="token keyword">def</span> <span class="token function">deal_error</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span> e<span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token triple-quoted-string string">""" 处理错误异常
        参数:
            e:异常
    """</span>
    log_str <span class="token operator">=</span> <span class="token string">'发生错误: %s'</span> <span class="token operator">%</span> e
    self<span class="token punctuation">.</span>write_log<span class="token punctuation">(</span>log_str<span class="token punctuation">)</span>
    sys<span class="token punctuation">.</span>exit<span class="token punctuation">(</span><span class="token punctuation">)</span>

<span class="token keyword">def</span> <span class="token function">write_log</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span> log_str<span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token triple-quoted-string string">""" 记录日志
        参数:
            log_str:日志
    """</span>
    time_now <span class="token operator">=</span> time<span class="token punctuation">.</span>localtime<span class="token punctuation">(</span><span class="token punctuation">)</span>
    date_now <span class="token operator">=</span> time<span class="token punctuation">.</span>strftime<span class="token punctuation">(</span><span class="token string">'%Y-%m-%d'</span><span class="token punctuation">,</span> time_now<span class="token punctuation">)</span>
    format_log_str <span class="token operator">=</span> <span class="token string">"%s ---&gt; %s \n "</span> <span class="token operator">%</span> <span class="token punctuation">(</span>date_now<span class="token punctuation">,</span> log_str<span class="token punctuation">)</span>
    <span class="token keyword">print</span><span class="token punctuation">(</span>format_log_str<span class="token punctuation">)</span>
    self<span class="token punctuation">.</span>log_file<span class="token punctuation">.</span>write<span class="token punctuation">(</span>format_log_str<span class="token punctuation">)</span>

<span class="token keyword">def</span> <span class="token function">get_file_list</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span> line<span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token triple-quoted-string string">""" 获取文件列表
        参数:
            line:
    """</span>
    file_arr <span class="token operator">=</span> self<span class="token punctuation">.</span>get_file_name<span class="token punctuation">(</span>line<span class="token punctuation">)</span>
    <span class="token comment"># 去除  . 和  ..</span>
    <span class="token keyword">if</span> file_arr<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token keyword">not</span> <span class="token keyword">in</span> <span class="token punctuation">[</span><span class="token string">'.'</span><span class="token punctuation">,</span> <span class="token string">'..'</span><span class="token punctuation">]</span><span class="token punctuation">:</span>
        self<span class="token punctuation">.</span>file_list<span class="token punctuation">.</span>append<span class="token punctuation">(</span>file_arr<span class="token punctuation">)</span>

<span class="token keyword">def</span> <span class="token function">get_file_name</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span> line<span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token triple-quoted-string string">""" 获取文件名
        参数:
            line:
    """</span>
    pos <span class="token operator">=</span> line<span class="token punctuation">.</span>rfind<span class="token punctuation">(</span><span class="token string">':'</span><span class="token punctuation">)</span>
    <span class="token keyword">while</span> <span class="token punctuation">(</span>line<span class="token punctuation">[</span>pos<span class="token punctuation">]</span> <span class="token operator">!=</span> <span class="token string">' '</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
        pos <span class="token operator">+=</span> <span class="token number">1</span>
    <span class="token keyword">while</span> <span class="token punctuation">(</span>line<span class="token punctuation">[</span>pos<span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token string">' '</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
        pos <span class="token operator">+=</span> <span class="token number">1</span>
    file_arr <span class="token operator">=</span> <span class="token punctuation">[</span>line<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> line<span class="token punctuation">[</span>pos<span class="token punctuation">:</span><span class="token punctuation">]</span><span class="token punctuation">]</span>
    <span class="token keyword">return</span> file_arr

if name == main:
my_ftp = MyFTP(“172.28.180.117”)
my_ftp.login(“ouyangpeng”, “ouyangpeng”)

<span class="token comment"># 下载单个文件</span>
my_ftp<span class="token punctuation">.</span>download_file<span class="token punctuation">(</span><span class="token string">"G:/ftp_test/XTCLauncher.apk"</span><span class="token punctuation">,</span> <span class="token string">"/App/AutoUpload/ouyangpeng/I12/Release/XTCLauncher.apk"</span><span class="token punctuation">)</span>

<span class="token comment"># 下载目录</span>
<span class="token comment"># my_ftp.download_file_tree("G:/ftp_test/", "App/AutoUpload/ouyangpeng/I12/")</span>

<span class="token comment"># 上传单个文件</span>
<span class="token comment"># my_ftp.upload_file("G:/ftp_test/Release/XTCLauncher.apk", "/App/AutoUpload/ouyangpeng/I12/Release/XTCLauncher.apk")</span>

<span class="token comment"># 上传目录</span>
<span class="token comment"># my_ftp.upload_file_tree("G:/ftp_test/", "/App/AutoUpload/ouyangpeng/I12/")</span>

my_ftp<span class="token punctuation">.</span>close<span class="token punctuation">(</span><span class="token punctuation">)</span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277

3.1 测试下载远程单个文件

我们将 程序入口改为如下所示的代码,测试下下载单个文件

测试前的测试环境如下图所示:
这里写图片描述

if __name__ == "__main__":
    my_ftp = MyFTP("172.28.180.117")
    my_ftp.login("ouyangpeng", "ouyangpeng")
# 下载单个文件
my_ftp.download_file("G:/ftp_test/XTCLauncher.apk", "/App/AutoUpload/ouyangpeng/I12/Release/XTCLauncher.apk")

my_ftp.close()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

运行结果为:

"C:\Code Python\JenkinsAPI\venv\Scripts\python.exe" "C:/Code Python/JenkinsAPI/ftptest.py"
2018-02-06 ---> 开始尝试连接到 172.28.180.117 

2018-02-06 —> 成功连接到 172.28.180.117

2018-02-06 —> 开始尝试登录到 172.28.180.117

2018-02-06 —> 成功登录到 172.28.180.117

2018-02-06 —> 220 (vsFTPd 2.3.5)

2018-02-06 —> download_file()—> local_path = G:/ftp_test/XTCLauncher.apk ,remote_path = /App/AutoUpload/ouyangpeng/I12/Release/XTCLauncher.apk

2018-02-06 —> local_file_size:-1 , remote_file_size:16749148

2018-02-06 —> >>>>>>>>>>>>下载文件 G:/ftp_test/XTCLauncher.apk … …

2018-02-06 —> close()—> FTP退出

Process finished with exit code 0

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

这里写图片描述

刷新下目录,查看文件已经下载成功!
这里写图片描述

3.2 测试下载远程目录

我们将 程序入口改为如下所示的代码,测试下载整个文件夹,运行之前的环境如下所示:

这里写图片描述

if __name__ == "__main__":
    my_ftp = MyFTP("172.28.180.117")
    my_ftp.login("ouyangpeng", "ouyangpeng")
# 下载目录
my_ftp.download_file_tree("G:/ftp_test/", "App/AutoUpload/ouyangpeng/I12/")

my_ftp.close()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

运行结果为:

"C:\Code Python\JenkinsAPI\venv\Scripts\python.exe" "C:/Code Python/JenkinsAPI/ftptest.py"
2018-02-06 ---> 开始尝试连接到 172.28.180.117 

2018-02-06 —> 成功连接到 172.28.180.117

2018-02-06 —> 开始尝试登录到 172.28.180.117

2018-02-06 —> 成功登录到 172.28.180.117

2018-02-06 —> 220 (vsFTPd 2.3.5)

download_file_tree()—> local_path = G:/ftp_test/ ,remote_path = App/AutoUpload/ouyangpeng/I12/
2018-02-06 —> 切换至目录: /App/AutoUpload/ouyangpeng/I12

2018-02-06 —> 远程目录 列表: [[‘d’, ‘Debug’], [‘d’, ‘Release’]]

download_file_tree()—> 下载目录: Debug
download_file_tree()—> local_path = G:/ftp_test/Debug ,remote_path = Debug
2018-02-06 —> 本地目录G:/ftp_test/Debug不存在,先创建本地目录

2018-02-06 —> 切换至目录: /App/AutoUpload/ouyangpeng/I12/Debug

2018-02-06 —> 远程目录 列表: []

2018-02-06 —> 返回上层目录 /App/AutoUpload/ouyangpeng/I12

download_file_tree()—> 下载目录: Release
download_file_tree()—> local_path = G:/ftp_test/Release ,remote_path = Release
2018-02-06 —> 本地目录G:/ftp_test/Release不存在,先创建本地目录

2018-02-06 —> 切换至目录: /App/AutoUpload/ouyangpeng/I12/Release

2018-02-06 —> 远程目录 列表: [[‘-’, ‘XTCLauncher.apk’]]

download_file()—> 下载文件: XTCLauncher.apk
2018-02-06 —> download_file()—> local_path = G:/ftp_test/Release\XTCLauncher.apk ,remote_path = XTCLauncher.apk

2018-02-06 —> local_file_size:-1 , remote_file_size:16749148

2018-02-06 —> >>>>>>>>>>>>下载文件 G:/ftp_test/Release\XTCLauncher.apk … …

2018-02-06 —> 返回上层目录 /App/AutoUpload/ouyangpeng/I12

2018-02-06 —> 返回上层目录 /App/AutoUpload/ouyangpeng

2018-02-06 —> close()—> FTP退出

Process finished with exit code 0

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

这里写图片描述

这里写图片描述

刷新下目录,查看整个目录已经下载成功!

这里写图片描述

目录下的文件也成功下载下来
这里写图片描述

3.3 测试上传单个文件到远程FTP服务器

我们将 程序入口改为如下所示的代码,测试下载整个文件夹,运行之前的环境如下所示:

这里写图片描述

if __name__ == "__main__":
    my_ftp = MyFTP("172.28.180.117")
    my_ftp.login("ouyangpeng", "ouyangpeng")
# 上传单个文件
my_ftp.upload_file("G:/ftp_test/Release/XTCLauncher.apk", "/App/AutoUpload/ouyangpeng/I12/Release/XTCLauncher.apk")

my_ftp.close()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

运行结果为:

"C:\Code Python\JenkinsAPI\venv\Scripts\python.exe" "C:/Code Python/JenkinsAPI/ftptest.py"
2018-02-06 ---> 开始尝试连接到 172.28.180.117 

2018-02-06 —> 成功连接到 172.28.180.117

2018-02-06 —> 开始尝试登录到 172.28.180.117

2018-02-06 —> 成功登录到 172.28.180.117

2018-02-06 —> 220 (vsFTPd 2.3.5)

2018-02-06 —> local_file_size:16749148 , remote_file_size:-1

2018-02-06 —> 上传: G:/ftp_test/Release/XTCLauncher.apk成功!

2018-02-06 —> close()—> FTP退出

Process finished with exit code 0

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

这里写图片描述

刷新下界面,可以看到文件上传成功了!

这里写图片描述

3.4 测试上传文件夹到远程FTP服务器

我们将 程序入口改为如下所示的代码,测试下载整个文件夹,运行之前的环境如下所示:

这里写图片描述

if __name__ == "__main__":
    my_ftp = MyFTP("172.28.180.117")
    my_ftp.login("ouyangpeng", "ouyangpeng")
# 上传目录
my_ftp.upload_file_tree("G:/ftp_test/", "/App/AutoUpload/ouyangpeng/I12/")

my_ftp.close()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

运行结果为:

"C:\Code Python\JenkinsAPI\venv\Scripts\python.exe" "C:/Code Python/JenkinsAPI/ftptest.py"
2018-02-06 ---> 开始尝试连接到 172.28.180.117 

2018-02-06 —> 成功连接到 172.28.180.117

2018-02-06 —> 开始尝试登录到 172.28.180.117

2018-02-06 —> 成功登录到 172.28.180.117

2018-02-06 —> 220 (vsFTPd 2.3.5)

2018-02-06 —> 切换至远程目录: /App/AutoUpload/ouyangpeng/I12

2018-02-06 —> 目录已存在 Debug ,具体错误描述为:550 Create directory operation failed.

2018-02-06 —> upload_file_tree()—> 上传目录: Debug

2018-02-06 —> 切换至远程目录: /App/AutoUpload/ouyangpeng/I12/Debug

2018-02-06 —> upload_file_tree()—> 上传目录: Release

2018-02-06 —> 切换至远程目录: /App/AutoUpload/ouyangpeng/I12/Release

2018-02-06 —> upload_file_tree()—> 上传文件: XTCLauncher.apk

2018-02-06 —> local_file_size:16749148 , remote_file_size:-1

2018-02-06 —> 上传: G:/ftp_test/Release\XTCLauncher.apk成功!

2018-02-06 —> upload_file_tree()—> 上传文件: v1.jpg

2018-02-06 —> local_file_size:203677 , remote_file_size:-1

2018-02-06 —> 上传: G:/ftp_test/v1.jpg成功!

2018-02-06 —> close()—> FTP退出

Process finished with exit code 0

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

这里写图片描述

这里写图片描述

刷新下界面,可以看到文件上传成功了!

这里写图片描述

这里写图片描述

3.5 解决中文编码奔溃的问题

这里写图片描述
准备上传含有中文的文件到FTP服务器的时候,会奔溃,奔溃如下所示:

2018-02-06 ---> 切换至远程目录: /App/AutoUpload/ouyangpeng/I12 

2018-02-06 —> upload_file_tree()—> 上传目录: Debug

2018-02-06 —> 切换至远程目录: /App/AutoUpload/ouyangpeng/I12/Debug

2018-02-06 —> upload_file_tree()—> 上传文件: Python编程快速上手__让繁琐工作自动化.pdf

2018-02-06 —> local_file_size:14773136 , remote_file_size:-1

Traceback (most recent call last):
File “C:/Code Python/JenkinsAPI/ftptest.py”, line 277, in <module>
my_ftp.upload_file_tree(“G:/ftp_test/”, “/App/AutoUpload/ouyangpeng/I12/”)
File “C:/Code Python/JenkinsAPI/ftptest.py”, line 203, in upload_file_tree
self.upload_file(src, local_name)
File “C:/Code Python/JenkinsAPI/ftptest.py”, line 172, in upload_file
self.ftp.storbinary(‘STOR %s’ % remote_file, file_handler, buf_size)
File “D:\Python\lib\ftplib.py”, line 502, in storbinary
with self.transfercmd(cmd, rest) as conn:
File “D:\Python\lib\ftplib.py”, line 397, in transfercmd
return self.ntransfercmd(cmd, rest)[0]
File “D:\Python\lib\ftplib.py”, line 363, in ntransfercmd
resp = self.sendcmd(cmd)
File “D:\Python\lib\ftplib.py”, line 270, in sendcmd
self.putcmd(cmd)
File “D:\Python\lib\ftplib.py”, line 197, in putcmd
self.putline(line)
File “D:\Python\lib\ftplib.py”, line 192, in putline
self.sock.sendall(line.encode(self.encoding))
UnicodeEncodeError: ‘latin-1’ codec can’t encode characters in position 11-16: ordinal not in range(256)

Process finished with exit code 1

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

这里写图片描述

提示我们

UnicodeEncodeError: 'latin-1' codec can't encode characters in position 11-16: ordinal not in range(256)

 
 
  • 1

查看 Python ftplib模块,默认的编码就是 latin-1

这里写图片描述

我们将这个ftp的编码修改下即可上传成功。将MyFTP的 init 方法修改下,设置下ftp的encoding为gbk即可

    def __init__(self, host, port=21):
        """ 初始化 FTP 客户端
        参数:
                 host:ip地址
             port:端口号
    """
    # print("__init__()---&gt; host = %s ,port = %s" % (host, port))

    self.host = host
    self.port = port
    self.ftp = FTP()
    # 重新设置下编码方式
    self.ftp.encoding = 'gbk'

    self.log_file = open("log.txt", "a")
    self.file_list = []
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

增加一句 self.ftp.encoding = 'gbk',即可重新设置encoding了。

这里写图片描述

再次运行即可成功上传,如下图所示:

运行结果为:

"C:\Code Python\JenkinsAPI\venv\Scripts\python.exe" "C:/Code Python/JenkinsAPI/ftptest.py"
2018-02-06 ---> 开始尝试连接到 172.28.180.117 

2018-02-06 —> 成功连接到 172.28.180.117

2018-02-06 —> 开始尝试登录到 172.28.180.117

2018-02-06 —> 成功登录到 172.28.180.117

2018-02-06 —> 220 (vsFTPd 2.3.5)

2018-02-06 —> 切换至远程目录: /App/AutoUpload/ouyangpeng/I12

2018-02-06 —> upload_file_tree()—> 上传目录: Debug

2018-02-06 —> 切换至远程目录: /App/AutoUpload/ouyangpeng/I12/Debug

2018-02-06 —> upload_file_tree()—> 上传文件: Python编程快速上手__让繁琐工作自动化.pdf

2018-02-06 —> local_file_size:14773136 , remote_file_size:-1

2018-02-06 —> 上传: G:/ftp_test/Python编程快速上手__让繁琐工作自动化.pdf成功!

2018-02-06 —> upload_file_tree()—> 上传目录: Release

2018-02-06 —> 切换至远程目录: /App/AutoUpload/ouyangpeng/I12/Release

2018-02-06 —> upload_file_tree()—> 上传文件: XTCLauncher.apk

2018-02-06 —> local_file_size:16749148 , remote_file_size:-1

2018-02-06 —> 上传: G:/ftp_test/Release\XTCLauncher.apk成功!

2018-02-06 —> upload_file_tree()—> 上传文件: v1.jpg

2018-02-06 —> local_file_size:203677 , remote_file_size:-1

2018-02-06 —> 上传: G:/ftp_test/v1.jpg成功!

2018-02-06 —> upload_file_tree()—> 上传文件: XTCLauncher.apk

2018-02-06 —> local_file_size:16749148 , remote_file_size:-1

2018-02-06 —> 上传: G:/ftp_test/XTCLauncher.apk成功!

2018-02-06 —> close()—> FTP退出

Process finished with exit code 0

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

这里写图片描述

这里写图片描述


四、参考链接

  • Python 2.7系列官方文档: https://docs.python.org/2/library/ftplib.html
  • Python 3.5系列官方文档:https://docs.python.org/3.5/library/ftplib.html
  • Python 3.6系列官方文档:https://docs.python.org/3.6/library/ftplib.html
  • http://blog.csdn.net/xiaoxianerqq/article/details/50698555
  • http://www.cppblog.com/fwxjj/archive/2011/12/14/162085.html
  • https://www.cnblogs.com/hltswd/p/6228992.html
  • http://bbs.chinaunix.net/thread-2333189-1-1.html

这里写图片描述

作者:欧阳鹏 欢迎转载,与人分享是进步的源泉!
转载请保留原文地址:http://blog.csdn.net/ouyang_peng/article/details/79271113

如果觉得本文对您有所帮助,欢迎您扫码下图所示的支付宝和微信支付二维码对本文进行随意打赏。您的支持将鼓励我继续创作!

这里写图片描述

**Markdown编辑器** 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。

新的改变

我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:

  1. 全新的界面设计 ,将会带来全新的写作体验;
  2. 在创作中心设置你喜爱的代码高亮样式,Markdown 将代码片显示选择的高亮样式 进行展示;
  3. 增加了 图片拖拽 功能,你可以将本地的图片直接拖拽到编辑区域直接展示;
  4. 全新的 KaTeX数学公式 语法;
  5. 增加了支持甘特图的mermaid语法1 功能;
  6. 增加了 多屏幕编辑 Markdown文章功能;
  7. 增加了 焦点写作模式、预览模式、简洁写作模式、左右区域同步滚轮设置 等功能,功能按钮位于编辑区域与预览区域中间;
  8. 增加了 检查列表 功能。

功能快捷键

撤销:Ctrl/Command + Z
重做:Ctrl/Command + Y
加粗:Ctrl/Command + B
斜体:Ctrl/Command + I
标题:Ctrl/Command + Shift + H
无序列表:Ctrl/Command + Shift + U
有序列表:Ctrl/Command + Shift + O
检查列表:Ctrl/Command + Shift + C
插入代码:Ctrl/Command + Shift + K
插入链接:Ctrl/Command + Shift + L
插入图片:Ctrl/Command + Shift + G
查找:Ctrl/Command + F
替换:Ctrl/Command + G

合理的创建标题,有助于目录的生成

直接输入1次#,并按下space后,将生成1级标题。
输入2次#,并按下space后,将生成2级标题。
以此类推,我们支持6级标题。有助于使用TOC语法后生成一个完美的目录。

如何改变文本的样式

强调文本 强调文本

加粗文本 加粗文本

标记文本

删除文本

引用文本

H2O is是液体。

210 运算结果是 1024.

插入链接与图片

链接: link.

图片: Alt

带尺寸的图片: Alt

居中的图片: Alt

居中并且带尺寸的图片: Alt

当然,我们为了让用户更加便捷,我们增加了图片拖拽功能。

如何插入一段漂亮的代码片

博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片.

// An highlighted block
var foo = 'bar';

生成一个适合你的列表

  • 项目
    • 项目
      • 项目
  1. 项目1
  2. 项目2
  3. 项目3
  • 计划任务
  • 完成任务

创建一个表格

一个简单的表格是这么创建的:

项目Value
电脑$1600
手机$12
导管$1

设定内容居中、居左、居右

使用:---------:居中
使用:----------居左
使用----------:居右

第一列第二列第三列
第一列文本居中第二列文本居右第三列文本居左

SmartyPants

SmartyPants将ASCII标点字符转换为“智能”印刷标点HTML实体。例如:

TYPEASCIIHTML
Single backticks'Isn't this fun?'‘Isn’t this fun?’
Quotes"Isn't this fun?"“Isn’t this fun?”
Dashes-- is en-dash, --- is em-dash– is en-dash, — is em-dash

创建一个自定义列表

Markdown
Text-to- HTML conversion tool
Authors
John
Luke

如何创建一个注脚

一个具有注脚的文本。2

注释也是必不可少的

Markdown将文本转换为 HTML

KaTeX数学公式

您可以使用渲染LaTeX数学表达式 KaTeX:

Gamma公式展示 Γ ( n ) = ( n − 1 ) ! ∀ n ∈ N \Gamma(n) = (n-1)!\quad\forall n\in\mathbb N Γ(n)=(n1)!nN 是通过欧拉积分

Γ ( z ) = ∫ 0 ∞ t z − 1 e − t d t   . \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,. Γ(z)=0tz1etdt.

你可以找到更多关于的信息 LaTeX 数学表达式here.

新的甘特图功能,丰富你的文章

Mon 06 Mon 13 Mon 20 已完成 进行中 计划一 计划二 现有任务 Adding GANTT diagram functionality to mermaid
  • 关于 甘特图 语法,参考 这儿,

UML 图表

可以使用UML图表进行渲染。 Mermaid. 例如下面产生的一个序列图:

张三 李四 王五 你好!李四, 最近怎么样? 你最近怎么样,王五? 我很好,谢谢! 我很好,谢谢! 李四想了很长时间, 文字太长了 不适合放在一行. 打量着王五... 很好... 王五, 你怎么样? 张三 李四 王五

这将产生一个流程图。:

链接
长方形
圆角长方形
菱形
  • 关于 Mermaid 语法,参考 这儿,

FLowchart流程图

我们依旧会支持flowchart的流程图:

Created with Raphaël 2.3.0 开始 我的操作 确认? 结束 yes no
  • 关于 Flowchart流程图 语法,参考 这儿.

导出与导入

导出

如果你想尝试使用此编辑器, 你可以在此篇文章任意编辑。当你完成了一篇文章的写作, 在上方工具栏找到 文章导出 ,生成一个.md文件或者.html文件进行本地保存。

导入

如果你想加载一篇你写过的.md文件,在上方工具栏可以选择导入功能进行对应扩展名的文件导入,
继续你的创作。


  1. mermaid语法说明 ↩︎

  2. 注脚的解释 ↩︎

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值