Как скачать большой файл в Python через FTP (с мониторингом и переподключением)?

ОБНОВЛЕНИЕ № 1

Код в вопросе работает довольно хорошо для стабильного соединения (например, локальной сети или интранета).

ОБНОВЛЕНИЕ № 2

Я реализовал FTPClient класс с ftplib, который может:

  1. контролировать ход загрузки
  2. переподключиться в случае таймаута или отключиться
  3. делает несколько попыток скачать файл
  4. показывает текущую скорость загрузки.

После повторного подключения он продолжает процесс загрузки с точки отключения (если это поддерживает FTP-сервер). Для подробностей смотрите мой ответ ниже.


Вопрос

Я должен реализовать задачу на python, которая ежедневно загружает кучу больших файлов (0,3-1,5 ГБ на файл * 200-300 файлов) через FTP, а затем выполняет некоторую обработку с файлами. Я сделал это через ftplib. Но время от времени он зависает и не может завершить загрузку некоторых файлов. Чтобы решить эту проблему, я начал играть с настройками KEEPALIVE, но я до сих пор не получил хороший результат

with closing(ftplib.FTP()) as ftp:
    try:
        ftp.connect(self.host, self.port, 30*60) #30 mins timeout
        # print ftp.getwelcome()
        ftp.login(self.login, self.passwd)
        ftp.set_pasv(True)
        ftp.sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
        ftp.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 75)
        ftp.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 60)
        with open(local_filename, 'w+b') as f:
            res = ftp.retrbinary('RETR %s' % orig_filename, f.write)

            if not res.startswith('226 Transfer complete'):
                logging.error('Downloaded of file {0} is not compile.'.format(orig_filename))
                os.remove(local_filename)
                return None

        os.rename(local_filename, self.storage + filename + file_ext)
        ftp.rename(orig_filename, orig_filename + '.copied')

        return filename + file_ext

    except:
            logging.exception('Error during download from FTP')

подробности

  • Обычно загрузка файла занимает 7-15 минут.
  • FTP-сервер всегда показывает мне в журналах, что файлы полностью загружены, но клиентская часть зависает. Не каждый раз, а время от времени.

Вопросы

  • Может ли это быть из-за отключения?
  • Как реализовать монитор для процесса загрузки и повторно подключить его в случае, если он отключен

1 ответ

Решение

Поскольку я не мог найти хороших предложений или примеров кода, я реализовал свое собственное решение. Огромное спасибо сообществу Stackru за некоторые идеи, которые я использовал в своем коде. Я поместил код в GitHub ( pyFTPclient) из-за размера кода (~ 120 строк).

Я проверил решение в сети плохого качества (включая мобильный интернет 3G), и это было хорошо для меня. Но, конечно, это может иметь некоторые ошибки.

Буду признателен за любые комментарии или предложения. Заранее спасибо.

Другие вопросы по тегам