Проверка, является ли объект на 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'
и это может определить это, однако дальнейшее чтение показало, что не все выходные данные имеют одинаковый формат.
Самый большой недостаток, который я вижу в этом методе, это то, что у меня нет разрешения сменить каталог на указанную папку; следовательно, он будет рассматриваться как файл.
Есть ли что-то, что я пропускаю или более чистый способ сделать это?
2 ответа
Нет лучшего способа (с протоколом FTP в целом, а не только с ftplib).
MLST
/MLSD
это единственный правильный и надежный способ.
Если вы не можете использовать MLST
/MLSD
, пытаясь CWD
это следующий лучший вариант.
Пытаюсь разобрать LIST
это запасной вариант. Но вы должны знать, что сервер использует формат листинга, который понимает ваша программа.
Вот функция, которую я использовал через 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
Объяснение:
Здесь все, что вам нужно, это циклически перемещаться по файлам и каталогам в пределах вашего предполагаемого каталога и выбирать каталоги. Но так как вы не можете сделать это так, как вы используете в ОС, вам нужно использовать ftplib.FTP.retrlines()
функция, которая извлекает список файлов или каталогов в режиме передачи ASCII, затем вы можете разделить каталоги, анализируя эти строки.