ftputil 简介
最近工作上需要定制一个 FTP 客户端工具,用来同步本地文件夹到 FTP 服务器上。这般粗活首选当然是 Python: 开发迅速,编写简洁,还能用 py2exe 打包独立分发。
但 Python 标准库对 FTP 的封装太底层,很不好用。在自己动手改进之前先放狗搜了一下,果然早有人忍不住,不但封装了 FTP 客户端,而且开源了。这就是 ftputil ,一个 Python 高层次接口 FTP 客户端库。
ftputil 的接口非常简单易用。一个 ftputil.FTPHost 对象就包括了 FTP 的上传下载和查询。整个接口还刻意模仿标准模块 os 的本地文件操作接口,上手不费吹灰之力。与 os 模块的文件操作接口保持一致还有个好处: 多态。本地文件和 FTP 远程文件操作接口一模一样,这样对已有的程序添加 FTP 存储支持,只需要把 os 模块换成 FTPHost 对象就成了。FTP 的操作对调用端代码是透明的,非常方便。
ftputil 还有个隐藏功能:对本地和远程 FTP 文件夹进行同步。也许作者认为这个功能还不成熟,并没在文档中提及。不过文件夹同步恰好是我需要的,自然毫不客气直接拿来使用!ftputil 源代码中的 ftp_sync 实现了同步功能。下面几行代码就实现了将本地文件夹同步到 FTP 服务器
from ftputil import *
from ftputil.ftp_error import *
from ftputil.ftp_sync import *
def sync(local_directory, ftp_host, remote_path, user=None, password=None):
with FTPHost(ftp_host, user, password) as remote:
print 'Login to FTP %s successfully as user %s' % (host, (user and user or 'anonymous'))
local = LocalHost()
syncer = Syncer(local, remote)
syncer.sync(local_directory, remote_path)
本来要自己实现的功能几行代码就搞定,真省事。
虽省事,却不省心,测试时发现了两个问题:
- FTP 服务器上以 . 开头的隐藏文件无法例出。解法是给 FTP 命令 LIST 加上参数 -a 显示所有文件
- 从 Windows 平台同步文件夹时,Windows 的文件分隔符 \ 被 FTP 服务器直接当做文件名的一部分,导制文件没有在目录下创建,而是新建另一个名为 dir\file.name 的文件。解法是使用 FTP 命令之前,先把路径中的文件分隔符替换成通用的 /。
这两个问题我遇到了,修好了。本着人人为我我为人人的开源精神,我给作者提了两个 bug (#62, #63),并跟作者一起在 ftputil v2.7 中修好了这两个问题。ftputil 的作者 Stefan 很好沟通,一点举手之劳赢得他的感谢,还挺有成就感的。
天下程序一大抄,看你会抄不会抄。不会抄的,键盘上的 ctrl c v 键一定是饱经风霜了吧; 会抄的,在发明轮子前,先找现成的轮子,找到了,会用了,从此工具箱中又多了一件趁手的兵器。这不比毫无积累的复制粘贴大法高出不少吗; 如果能再进一步,不怕麻烦,帮着修补轮子,让它更加结实好用,利人利己,也算是抄亦有道了吧。
谢谢 Stefan 给 Python 社区贡献的好轮子!