Определите, является ли список каталогом или файлом в Python по FTP

Python имеет стандартный библиотечный модуль ftplib для работы с FTP. У него есть два способа получить список содержимого каталога. Один FTP.nlst(),, вернет список содержимого каталога с именем каталога в качестве аргумента. (Он вернет имя файла, если вместо этого будет указано имя файла.) Это надежный способ перечислить содержимое каталога, но не дает никаких указаний на то, является ли каждый элемент в списке файлом или каталогом. Другой метод - FTP.dir() это вывод в формате строки списка содержимого каталога, указанного в качестве аргумента (или атрибутов файла с учетом имени файла).

Согласно предыдущему вопросу о переполнении стека , анализ результатов dir() может быть хрупким (разные серверы могут возвращать разные строки). Я ищу способ перечислить только каталоги, содержащиеся в другом каталоге через FTP. Насколько мне известно, очистка d строки с правами доступа - единственное решение, которое я придумал, но я не могу гарантировать, что разрешения будут отображаться в одном и том же месте на разных серверах. Есть ли более надежное решение для идентификации каталогов через FTP?

Ответов (3)

Решение

К сожалению, FTP не имеет команды для вывода списка только папок, поэтому анализ результатов, которые вы получаете от ftp.dir (), был бы «лучшим».

Простое приложение, предполагающее стандартный результат от ls (не Windows ftp)

from ftplib import FTP

ftp = FTP(host, user, passwd)
for r in ftp.dir():
    if r.upper().startswith('D'):
        print r[58:]  # Starting point

Стандартные команды FTP

Пользовательские команды FTP

Другой способ - предположить, что все является каталогом, и попытаться перейти в него. Если это успешно, это каталог, но если это вызывает ftplib.error_perm, вероятно, это файл. Вы можете поймать, а затем поймать исключение. Конечно, это не самый безопасный вариант, но и анализ сумасшедшей строки на предмет ведущих букв не означает.

Пример

def processRecursive(ftp,directory):
    ftp.cwd(directory)
    #put whatever you want to do in each directory here
    #when you have called processRecursive with a file, 
    #the command above will fail and you will return


    #get the files and directories contained in the current directory
    filenames = []
    ftp.retrlines('NLST',filenames.append)
    for name in filenames:
        try:
            processRecursive(ftp,name)
        except ftplib.error_perm:
            #put whatever you want to do with files here

    #put whatever you want to do after processing the files 
    #and sub-directories of a directory here

Если FTP-сервер поддерживает MLSD команду, проверьте этот ответ на наличие пары полезных классов ( FTPDirectory и FTPTree ).