这里写自定义目录标题
欢迎使用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__()---> 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()---> 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">'>>>>>>>>>>>>下载文件 %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()---> 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()---> 下载目录: %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()---> 下载文件: %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()---> 上传目录: %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()---> 上传文件: %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()---> 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 ---> %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__()---> 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 将代码片显示选择的高亮样式 进行展示;
- 增加了 图片拖拽 功能,你可以将本地的图片直接拖拽到编辑区域直接展示;
- 全新的 KaTeX数学公式 语法;
- 增加了支持甘特图的mermaid语法1 功能;
- 增加了 多屏幕编辑 Markdown文章功能;
- 增加了 焦点写作模式、预览模式、简洁写作模式、左右区域同步滚轮设置 等功能,功能按钮位于编辑区域与预览区域中间;
- 增加了 检查列表 功能。
功能快捷键
撤销: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.
图片:
带尺寸的图片:
居中的图片:
居中并且带尺寸的图片:
当然,我们为了让用户更加便捷,我们增加了图片拖拽功能。
如何插入一段漂亮的代码片
去博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片
.
// An highlighted block
var foo = 'bar';
生成一个适合你的列表
- 项目
- 项目
- 项目
- 项目
- 项目1
- 项目2
- 项目3
- 计划任务
- 完成任务
创建一个表格
一个简单的表格是这么创建的:
项目 | Value |
---|---|
电脑 | $1600 |
手机 | $12 |
导管 | $1 |
设定内容居中、居左、居右
使用:---------:
居中
使用:----------
居左
使用----------:
居右
第一列 | 第二列 | 第三列 |
---|---|---|
第一列文本居中 | 第二列文本居右 | 第三列文本居左 |
SmartyPants
SmartyPants将ASCII标点字符转换为“智能”印刷标点HTML实体。例如:
TYPE | ASCII | HTML |
---|---|---|
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)=(n−1)!∀n∈N 是通过欧拉积分
Γ ( z ) = ∫ 0 ∞ t z − 1 e − t d t . \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,. Γ(z)=∫0∞tz−1e−tdt.
你可以找到更多关于的信息 LaTeX 数学表达式here.
新的甘特图功能,丰富你的文章
- 关于 甘特图 语法,参考 这儿,
UML 图表
可以使用UML图表进行渲染。 Mermaid. 例如下面产生的一个序列图:
这将产生一个流程图。:
- 关于 Mermaid 语法,参考 这儿,
FLowchart流程图
我们依旧会支持flowchart的流程图:
- 关于 Flowchart流程图 语法,参考 这儿.
导出与导入
导出
如果你想尝试使用此编辑器, 你可以在此篇文章任意编辑。当你完成了一篇文章的写作, 在上方工具栏找到 文章导出 ,生成一个.md文件或者.html文件进行本地保存。
导入
如果你想加载一篇你写过的.md文件,在上方工具栏可以选择导入功能进行对应扩展名的文件导入,
继续你的创作。
注脚的解释 ↩︎