Я пытался решить проблему, когда мы загружаем файл с 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?