Проверка, является ли объект на FTP-сервере файлом или каталогом с помощью Python и ftplib

Используя Python и ftplib, я пишу общую функцию, чтобы проверить, являются ли элементы в каталоге FTP файлами или каталогами. Поскольку использование функции MLSD может не обязательно работать со всеми серверами (один из моих вариантов использования не предусматривает этого), я прибег к этому эффективному, но грубому способу определения ее, пытаясь сменить каталог на объект и если объект файла возникает исключение, и тип файла устанавливается соответствующим образом.

file_type = ''
try:
    ftp.cwd(item_name)
    file_type = 'dir'
    ftp.cwd(cur_path)
except ftplib.error_perm:
    file_type = 'file'

Я просмотрел документацию по Интернету и библиотеке в поисках других методов, но не могу найти тех, которые подойдут для большинства случаев.

Например, используя функцию dir, я могу проверить, является ли первый символ 'd', и это может определить его, однако дальнейшее чтение показало, что не весь вывод имеет одинаковый формат.

Самый большой недостаток, который я вижу в этом методе, заключается в том, что у меня нет разрешения на изменение каталога в указанную папку; следовательно, он будет рассматриваться как файл.

Есть ли что-то, чего мне не хватает, или более чистый способ сделать это?


person dgouder    schedule 27.04.2016    source источник


Ответы (2)


Нет лучшего способа (с протоколом FTP в целом, а не только с ftplib).

_1 _ / _ 2_ - единственный правильный и надежный способ.

Если вы не можете использовать _3 _ / _ 4_, попробуйте CWD - следующий лучший вариант.

Попытка разобрать LIST - это запасной вариант. Но вам нужно знать, что сервер использует формат листинга, который понимает ваша программа.

person Martin Prikryl    schedule 27.04.2016

Вот функция, которую я использовал в FTP-версии os.walk для FTP-серверов. Вот ссылка на github, если вы хотите увидеть полный код https://github.com/Kasramvd/FTPwalk:

def listdir(self, connection, _path):
    file_list, dirs, nondirs = [], [], []
    try:
        connection.cwd(_path)
    except:
        return [], []

    connection.retrlines('LIST', lambda x: file_list.append(x.split()))
    for info in file_list:
        ls_type, name = info[0], info[-1]
        if ls_type.startswith('d'):
            dirs.append(name)
        else:
            nondirs.append(name)
    return dirs, nondirs

Объяснение:

Здесь все, что вам нужно, это перебрать файлы и каталоги в предполагаемом каталоге и выбрать каталоги. Но поскольку вы не можете сделать это так же, как в ОС, вам необходимо использовать _ 3_, которая получает список файлов или каталогов в режиме передачи ASCII, после чего вы можете разделить каталоги, проанализировав эти строки.

person kasravnd    schedule 27.04.2016