Python FTP 教程
Python FTP 编程 教程展示了如何使用ftplib
库在 Python 中使用 FTP。 我们将连接到 FTP 服务器,列出目录,下载和上传文件。
FTP
文件传输协议(FTP)是用于在计算机网络上的客户端和服务器之间传输计算机文件的标准网络协议。 客户端和服务器使用一组 FTP 命令进行通信,例如 DELE,RETR 或 CWD。
许多服务器为 FTP 服务提供匿名 FTP 访问。 例如,有些 Linux 托管站点提供了一个匿名 FTP 帐户来下载分发映像。
Python ftplib
Python ftplib
是实现 FTP 协议客户端的模块。 它包含一个 FTP 客户端类和一些帮助程序功能。
Python FTP
类
ftplib.FTP()
创建 FTP 类的新实例。 给定主机后,将使用connect()
方法建立与主机的连接。
上下文管理器
与 Python 3 不同,Python 2 没有使用 FTP 类实现的上下文管理器。 因此,在处理连接对象时,Python 2 代码需要稍微不同的方法。
| import ftplib
with ftplib.FTP('ftp.debian.org') as ftp:
|
with
命令将自动关闭与 Python 3 代码的服务器连接。
| import ftplib
from contextlib import closing
with closing(ftplib.FTP('ftp.zetcode.com')) as ftp:
|
对于 Python 2 代码,我们需要使用contextlib
模块的closing
方法。
欢迎消息
getwelcome()
返回服务器为响应初始连接而发送的欢迎消息。 该消息可能包含一些对用户有用的信息。
welcome.py
| #!/usr/bin/python3
import ftplib
with ftplib.FTP('ftp.debian.org') as ftp:
print(ftp.getwelcome())
|
该示例创建与 Debian FTP 服务器的连接,该服务器具有一个匿名帐户并返回其欢迎消息。
| $ ./welcome.py
220 ftp.debian.org FTP server
|
这是程序的输出。
目录列表
dir()
方法产生一个目录列表。
listing.py
| #!/usr/bin/python3
import ftplib
with ftplib.FTP('ftp.debian.org') as ftp:
try:
ftp.login()
files = []
ftp.dir(files.append)
print(files)
except ftplib.all_errors as e:
print('FTP error:', e)
|
该示例连接到ftp.debian.org
主机,并检索初始登录目录的目录列表。
当login()
方法没有参数时; 我们连接到 FTP 站点的匿名帐户。
| files = []
ftp.dir(files.append)
|
dir()
方法产生目录列表,并将数据添加到列表中。
| $ ./listing.py
['drwxr-xr-x 9 1176 1176 4096 Sep 26 15:07 debian']
|
这是输出。
FTP 命令
FTP 客户端将命令发送到 FTP 服务器,例如PWD
或RETR
。 ftplib 包含几种包装这些命令的方法。 使用sendcmd()
或voidcmd()
方法发送命令。
ftp_commands.py
| #!/usr/bin/python3
import ftplib
with ftplib.FTP('ftp.debian.org') as ftp:
try:
ftp.login()
wdir = ftp.sendcmd('PWD')
print(ftplib.parse257(wdir))
wdir2 = ftp.pwd()
print(wdir2)
except ftplib.all_errors as e:
print('FTP error:', e)
|
该示例通过直接发送PWD
命令并使用pwd()
方法来检索当前工作目录。
| wdir = ftp.sendcmd('PWD')
|
我们使用sendcmd()
方法发送PWD
命令。
| print(ftplib.parse257(wdir))
|
parse257()
是一个帮助程序方法,它从返回的字符串中检索目录,该字符串还包含状态代码。
| wdir2 = ftp.pwd()
print(wdir2)
|
在这里,我们使用pwd()
方法检索当前工作目录。
这是输出。
变更目录
cwd()
方法更改当前工作目录。
change_directory.py
| #!/usr/bin/python3
import ftplib
with ftplib.FTP('ftp.debian.org') as ftp:
try:
ftp.login()
wdir = ftp.pwd()
print(wdir)
ftp.cwd('debian')
wdir2 = ftp.pwd()
print(wdir2)
except ftplib.all_errors as e:
print('FTP error:', e)
|
该示例使用cmd()
方法更改为debian
文件夹。
| $ ./change_directory.py
/
/debian
|
这是输出。
创建目录
使用mkd()
方法创建目录。 此操作需要具有足够特权的用户帐户; 它不适用于匿名帐户。
create_directory.py
| #!/usr/bin/python3
import ftplib
from contextlib import closing
with closing(ftplib.FTP('ftp.example.com')) as ftp:
try:
ftp.login('user7', 's$cret')
ftp.mkd('newdir')
files = []
ftp.retrlines('LIST', files.append)
for fl in files:
print(fl)
except ftplib.all_errors as e:
print('FTP error:', e)
|
该示例连接到 FTP 服务器,并在登录文件夹中创建一个新目录。
| ftp.login('user7', 's$cret')
|
我们使用login()
方法登录。
使用mkd()
方法创建一个新目录。
| files = []
ftp.retrlines('LIST', files.append)
|
使用LIST
FTP 命令,我们检索文件列表和有关这些文件的信息。 该列表存储在files
列表中。
| $ ./create_directory.py
drwx------ 6 zetcode.com 117992 7 Sep 27 14:58 .
drwx------ 6 zetcode.com 117992 7 Sep 27 14:58 ..
-rw------- 1 zetcode.com 117992 151 Jul 31 2015 .htaccess
drwxr-xr-x 2 0 0 4096 Sep 27 01:16 logs
drwx---r-x 2 zetcode.com 117992 2 Sep 27 14:58 newdir
drwx------ 3 zetcode.com 117992 3 Mar 11 2011 sub
drwx------ 26 zetcode.com 117992 31 Sep 25 15:32 web
|
从输出中我们可以看到newdir
已创建。
获取文本文件的大小
SIZE
命令及其等效的size()
方法是确定文件大小的非标准方法。 尽管没有标准化,但是它由许多服务器实现。
text_file_size.py
| #!/usr/bin/python3
import ftplib
with ftplib.FTP('ftp.debian.org') as ftp:
try:
ftp.login()
size = ftp.size('debian/README')
print(size)
except ftplib.all_errors as e:
print('FTP error:', e)
|
该示例使用size()
方法检索 README 文件的大小。
获取二进制文件的大小
要确定二进制文件的大小,我们必须切换到二进制模式。
binary_file_size.py
| #!/usr/bin/python3
import ftplib
with ftplib.FTP('ftp.debian.org') as ftp:
try:
ftp.login()
# TYPE A for ASCII mode
ftp.sendcmd('TYPE I')
size = ftp.size('debian/ls-lR.gz')
print(size)
except ftplib.all_errors as e:
print('FTP error:', e)
|
该示例确定二进制文件的大小。
我们使用TYPE I
命令进入二进制模式。
| size = ftp.size('debian/ls-lR.gz')
|
我们得到一个二进制文件的大小。
下载文本文件
要下载文本文件,我们使用RETR
FTP 命令。
download_text_file.py
| #!/usr/bin/python3
import ftplib
import os
with ftplib.FTP('ftp.debian.org') as ftp:
file_orig = '/debian/README'
file_copy = 'README'
try:
ftp.login()
with open(file_copy, 'w') as fp:
res = ftp.retrlines('RETR ' + file_orig, fp.write)
if not res.startswith('226 Transfer complete'):
print('Download failed')
if os.path.isfile(file_copy):
os.remove(file_copy)
except ftplib.all_errors as e:
print('FTP error:', e)
if os.path.isfile(file_copy):
os.remove(file_copy)
|
该示例从ftp.debian.org
服务器下载文本文件。
| with open(file_copy, 'w') as fp:
res = ftp.retrlines('RETR ' + file_orig, fp.write)
|
我们获取文件并写入本地副本文件。
| if not res.startswith('226 Transfer complete'):
print('Download failed')
if os.path.isfile(file_copy):
os.remove(file_copy)
|
如果下载失败,我们会打印一条错误消息并删除本地文件。
上传文本文件
具有storlines()
方法的STOR
命令用于上传文本文件。
upload_text_file.py
| #!/usr/bin/python3
import ftplib
with ftplib.FTP('ftp.example.com') as ftp:
filename = 'README'
try:
ftp.login('user7', 's$cret')
with open(filename, 'rb') as fp:
res = ftp.storlines("STOR " + filename, fp)
if not res.startswith('226 Transfer complete'):
print('Upload failed')
except ftplib.all_errors as e:
print('FTP error:', e)
|
在此示例中,我们将文本文件上传到 FTP 服务器。
在本教程中,我们使用了 Python ftplib
。