代码之家  ›  专栏  ›  技术社区  ›  andrewrk

使用python的ftplib获取目录列表,可移植

  •  49
  • andrewrk  · 技术社区  · 16 年前

    在python中,可以使用ftplib来完全支持ftp。但是,获得目录列表的首选方法是:

    # File: ftplib-example-1.py
    
    import ftplib
    
    ftp = ftplib.FTP("www.python.org")
    ftp.login("anonymous", "ftplib-example-1")
    
    data = []
    
    ftp.dir(data.append)
    
    ftp.quit()
    
    for line in data:
        print "-", line
    

    收益率:

    $ python ftplib-example-1.py
    - total 34
    - drwxrwxr-x  11 root     4127         512 Sep 14 14:18 .
    - drwxrwxr-x  11 root     4127         512 Sep 14 14:18 ..
    - drwxrwxr-x   2 root     4127         512 Sep 13 15:18 RCS
    - lrwxrwxrwx   1 root     bin           11 Jun 29 14:34 README -> welcome.msg
    - drwxr-xr-x   3 root     wheel        512 May 19  1998 bin
    - drwxr-sr-x   3 root     1400         512 Jun  9  1997 dev
    - drwxrwxr--   2 root     4127         512 Feb  8  1998 dup
    - drwxr-xr-x   3 root     wheel        512 May 19  1998 etc
    ...
    

    我想这个想法是通过解析结果得到目录列表。然而,这个列表直接依赖于ftp服务器格式化列表的方式。编写代码是非常麻烦的,因为这需要预测FTP服务器可能格式化此列表的所有不同方式。

    是否有一种可移植的方法来获取一个包含目录列表的数组?

    (数组应该只有文件夹名。)

    7 回复  |  直到 7 年前
        1
  •  106
  •   Nathan Smith Hilborn    7 年前

    尝试使用 ftp.nlst(dir) .

    但是,请注意,如果文件夹为空,则可能引发错误:

    files = []
    
    try:
        files = ftp.nlst()
    except ftplib.error_perm, resp:
        if str(resp) == "550 No files found":
            print "No files in this directory"
        else:
            raise
    
    for f in files:
        print f
    
        2
  •  24
  •   Giampaolo Rodolà    13 年前

    解析ftp目录列表的可靠/标准化方法是使用mlsd命令,到目前为止,所有最新的/体面的ftp服务器都应该支持该命令。

    import ftplib
    f = ftplib.FTP()
    f.connect("localhost")
    f.login()
    ls = []
    f.retrlines('MLSD', ls.append)
    for entry in ls:
        print entry
    

    上面的代码将打印:

    modify=20110723201710;perm=el;size=4096;type=dir;unique=807g4e5a5; tests
    modify=20111206092323;perm=el;size=4096;type=dir;unique=807g1008e0; .xchat2
    modify=20111022125631;perm=el;size=4096;type=dir;unique=807g10001a; .gconfd
    modify=20110808185618;perm=el;size=4096;type=dir;unique=807g160f9a; .skychart
    ...
    

    从python 3.3开始,ftplib将提供一种具体的方法:

        3
  •  2
  •   Garth Kidd    16 年前

    没有标准的布局 LIST 反应。你必须编写代码来处理最流行的布局。我先从Linux开始 ls 和Windows服务器 DIR 格式。不过,有很多种类。

    回到 nlst 方法(返回 NLST 命令)如果无法解析较长的列表。对于加分,作弊:可能包含已知文件名的行中最长的数字就是它的长度。

        4
  •  1
  •   Steve Saporta    10 年前

    我碰巧遇到了一个似乎不支持MLSD的FTP服务器(rackspace云站点虚拟服务器)。但是我需要几个文件信息字段,比如大小和时间戳,而不仅仅是文件名,所以我必须使用dir命令。在这个服务器上,dir的输出看起来非常像op的输出。如果它能帮助任何人,这里有一个小的python类,它解析一行这样的输出来获取文件名、大小和时间戳。

    导入日期时间

    class FtpDir:
        def parse_dir_line(self, line):
            words = line.split()
            self.filename = words[8]
            self.size = int(words[4])
            t = words[7].split(':')
            ts = words[5] + '-' + words[6] + '-' + datetime.datetime.now().strftime('%Y') + ' ' + t[0] + ':' + t[1]
            self.timestamp = datetime.datetime.strptime(ts, '%b-%d-%Y %H:%M')
    

    我知道,不是很便携,但很容易扩展或修改以处理各种不同的FTP服务器。

        5
  •  0
  •   Jeeva    7 年前

    这是从python文档

    >>> from ftplib import FTP_TLS
    >>> ftps = FTP_TLS('ftp.python.org')
    >>> ftps.login()           # login anonymously before securing control 
    channel
    >>> ftps.prot_p()          # switch to secure data connection
    >>> ftps.retrlines('LIST') # list directory content securely
    total 9
    drwxr-xr-x   8 root     wheel        1024 Jan  3  1994 .
    drwxr-xr-x   8 root     wheel        1024 Jan  3  1994 ..
    drwxr-xr-x   2 root     wheel        1024 Jan  3  1994 bin
    drwxr-xr-x   2 root     wheel        1024 Jan  3  1994 etc
    d-wxrwxr-x   2 ftp      wheel        1024 Sep  5 13:43 incoming
    drwxr-xr-x   2 root     wheel        1024 Nov 17  1993 lib
    drwxr-xr-x   6 1094     wheel        1024 Sep 13 19:07 pub
    drwxr-xr-x   3 root     wheel        1024 Jan  3  1994 usr
    -rw-r--r--   1 root     root          312 Aug  1  1994 welcome.msg
    
        6
  •  0
  •   pacholik    7 年前

    这对我的代码有帮助。

    当我尝试只填充一种类型的文件,并通过在每行上添加一个测试条件在屏幕上显示它们时。

    这样地

    elif command == 'ls':
        print("directory of ", ftp.pwd())
        data = []
        ftp.dir(data.append)
    
        for line in data:
            x = line.split(".")
            formats=["gz", "zip", "rar", "tar", "bz2", "xz"]
            if x[-1] in formats:
                print ("-", line)
    
        7
  •  0
  •   chill_turner    7 年前

    我在这里找到了我的方法,同时试图获得文件名,最后修改的邮票,文件大小等,并想添加我的代码。只花了几分钟就编写了一个循环来解析 ftp.dir(dir_list.append) 利用python std lib之类的东西 strip() (清除文本行)和 split() 创建数组。

    ftp = FTP('sick.domain.bro')
    ftp.login()
    ftp.cwd('path/to/data')
    
    dir_list = []
    ftp.dir(dir_list.append)
    
    # main thing is identifing which char marks start of good stuff
    # '-rw-r--r--   1 ppsrt    ppsrt      545498 Jul 23 12:07 FILENAME.FOO
    #                               ^  (that is line[29])
    
    for line in dir_list:
       print line[29:].strip().split(' ') # got yerself an array there bud!
       # EX ['545498', 'Jul', '23', '12:07', 'FILENAME.FOO']