Узнайте различия между списками каталогов по времени A и B на FTP - PullRequest
0 голосов
/ 03 января 2019

Я хочу создать скрипт, который узнает, какие файлы на FTP-сервере новые, а какие уже обработаны.
Для каждого файла на FTP мы считываем информацию, анализируем ее и записываем необходимую нам информацию в нашу базу данных. Файлы представляют собой xml-файлы, но должны быть переведены.

В данный момент я использую mlsd() для получения списка, но это занимает до 4 минут, потому что в этом каталоге уже 15.000 файлов - это будет более ежедневно.

Вместо того, чтобы сравнивать этот список со старым списком, который я сохранил в текстовом файле, я хотел бы знать, есть ли лучшие возможности.
Поскольку эта задача должна выполняться «вживую», она будет заканчиваться cronjob каждые 1-2 минуты. Если этот метод занимает много времени, это не сработает.

Решение должно быть на PHP или Python.

def handle(self, *args, **options):
    ftp = FTP_TLS(host=host)
    ftp.login(user,passwd)
    ftp.prot_p()
    list = ftp.mlsd("...")
    for item in list:
       print(item[0] + " => " + item[1]['modify'])

Этот пример кода уже выполняется 4 минуты.

Ответы [ 2 ]

0 голосов
/ 03 января 2019

Я всегда старался избегать просмотра папки, чтобы найти то, что могло измениться. Я предпочел установить выделенный рабочий процесс. Когда файлы могут быть добавлены только (или новые версии существующих файлов), я попытался использовать рабочий процесс, в котором файлы добавляются в один каталог, а затем переходят в другие каталоги, где они архивируются. Обработка может происходить в каталоге, где файлы удаляются после использования или когда они копируются / перемещаются из папки в другую.

В качестве небольшого плюса я также использую шаблон копирования / переименования: сначала файлы копируются с использованием временного имени (например, префикса или суффикса .t) и переименовываются по окончании копирования. Это предотвращает попытки обработки файла, который не полностью скопирован. Хорошо, раньше это было важнее, когда у нас были медленные линии, но нужно как можно больше избегать условий гонки, и это позволяет использовать демон, который опрашивает папку каждые 10 секунд или меньше.

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

0 голосов
/ 03 января 2019

Если FTP - ваш единственный интерфейс с сервером, нет лучшего способа, чем то, что вы уже делаете.

За исключением, может быть, если ваш сервер поддерживает нестандартные -t, переключитесь на LIST / NLST команд, который возвращает список, отсортированный по временным меткам.
См. Как получить файлы в папке FTP, отсортированные по времени изменения .

И если требуется много времени, это загрузкасписок файлов (не инициирование загрузки).В этом случае вы можете запросить отсортированный список, но загрузить только новые новые файлы, прервав список, как только найдете первый уже обработанный файл.

Пример того, как прервать загрузку списка файлов, см .:
Загрузите первые N строк текстового файла в ftp с помощью ftplib.retrlines

Примерно так:

class AbortedListing(Exception):
    pass

def collectNewFiles(s):
    if isProcessedFile(s): # your code to detect if the file was processed already
        print("We know this file already: " + s + " - aborting")
        raise AbortedListing()
    print("New file: " + s)

try:
    ftp.retrlines("NLST -t /path", collectNewFiles)
except AbortedListing:
    # read/skip response
    ftp.getmultiline()
...