跳转至

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 代码需要稍微不同的方法。

1
2
3
import ftplib 

with ftplib.FTP('ftp.debian.org') as ftp:

with命令将自动关闭与 Python 3 代码的服务器连接。

1
2
3
4
import ftplib 
from contextlib import closing

with closing(ftplib.FTP('ftp.zetcode.com')) as ftp:

对于 Python 2 代码,我们需要使用contextlib模块的closing方法。

欢迎消息

getwelcome()返回服务器为响应初始连接而发送的欢迎消息。 该消息可能包含一些对用户有用的信息。

welcome.py
1
2
3
4
5
6
#!/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主机,并检索初始登录目录的目录列表。

try:
    ftp.login()  

login()方法没有参数时; 我们连接到 FTP 站点的匿名帐户。

1
2
3
files = []

ftp.dir(files.append)

dir()方法产生目录列表,并将数据添加到列表中。

$ ./listing.py 
['drwxr-xr-x    9 1176     1176         4096 Sep 26 15:07 debian']

这是输出。

FTP 命令

FTP 客户端将命令发送到 FTP 服务器,例如PWDRETR。 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()方法检索当前工作目录。

1
2
3
$ ./ftp_commands.py 
/
/

这是输出。

变更目录

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文件夹。

1
2
3
$ ./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()方法登录。

ftp.mkd('newdir') 

使用mkd()方法创建一个新目录。

1
2
3
files = []

ftp.retrlines('LIST', files.append)

使用LIST FTP 命令,我们检索文件列表和有关这些文件的信息。 该列表存储在files列表中。

1
2
3
4
5
6
7
8
$ ./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) 

该示例确定二进制文件的大小。

ftp.sendcmd('TYPE I') 

我们使用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服务器下载文本文件。

1
2
3
with open(file_copy, 'w') as fp:

    res = ftp.retrlines('RETR ' + file_orig, fp.write)

我们获取文件并写入本地副本文件。

1
2
3
4
5
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