1

Я пытался решить проблему, когда мы загружаем файл с ftp/ftps. Файл успешно загружен, но после завершения загрузки файла операции не выполняются. Не произошло ошибок, которые могли бы дать больше информации о проблеме. Я попытался найти это в stackoverflow и нашел эту ссылку, в которой говорится о похожей формулировке проблемы и похоже, что я столкнулся с похожей проблемой, хотя я не уверен. Нужна немного больше помощи в решении проблемы.

Я попытался установить тайм-аут соединения FTP на 60 минут, но с меньшей помощью. До этого я использовал retrbinary() из ftplib, но там возникает та же проблема. Я попытался передать разные размеры блоков и окон, но с этим также проблема была воспроизводимой.

Я пытаюсь загрузить файл размером ~ 3 ГБ из кластера AWS EMR. Пример кода написан ниже

def download_ftp(self, ip, port, user_name, password, file_name, target_path):
try:
    os.chdir(target_path)
    ftp = FTP(host=ip)
    ftp.connect(port=int(port), timeout=3000)
    ftp.login(user=user_name, passwd=password)

    if ftp.nlst(file_name) != []:
        dir = os.path.split(file_name)
        ftp.cwd(dir[0])
        for filename in ftp.nlst(file_name):
            sock = ftp.transfercmd('RETR ' + filename)

            def background():
                fhandle = open(filename, 'wb')
                while True:
                    block = sock.recv(1024 * 1024)
                    if not block:
                        break
                    fhandle.write(block)
                sock.close()

            t = threading.Thread(target=background)
            t.start()
            while t.is_alive():
                t.join(60)
                ftp.voidcmd('NOOP')
            logger.info("File " + filename + " fetched successfully")
        return True
    else:
        logger.error("File " + file_name + " is not present in FTP")

except Exception, e:
    logger.error(e)
    raise

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

Я не очень разбираюсь в настройках тайм-аута на уровне FTP-сервера, поэтому не знал, что и как нужно изменить. Я в основном хочу написать общий загрузчик FTP, который может помочь в загрузке файлов с FTP/FTPS.

Когда я использую метод retrbinary() в ftplib и устанавливаю уровень отладки 2.

ftp.set_debuglevel(2)

Ниже журналы печатаются.

cmd 'TYPE I' положить 'TYPE I\r\n' get '200 Тип установлен в I.\r\n' соответственно '200 Тип установлен в I.' cmd 'PASV' put 'PASV\r\n' get '227 Вход в пассивный режим (64,27,160,28,133,251).\r\n' resp '227 Вход в пассивный режим (64,27,160,28,133,251).' CMD «Загружать FFFT_BRA_PM_R_201711.txt» положить «RETR FFFT_BRA_PM_R_201711.txt\ г \ п» получить «150 Открытие соединения данных BINARY режим для FFFT_BRA_PM_R_201711.txt.\ г \ п» соответственно «150 Открытие соединения данных BINARY режим для FFFT_BRA_PM_R_201711.txt.'

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

Как мне добиться того же в коде Python?

0