Python: Das Herunterladen von Dateien mit ftplib bleibt für immer hängen, nachdem die Datei erfolgreich heruntergeladen wurde

335
Manish Mehra

Ich habe versucht, ein Problem zu beheben, das beim Herunterladen einer Datei von ftp / ftps auftrat. Die Datei wird erfolgreich heruntergeladen, aber nach Abschluss des Dateidownloads wird keine Operation ausgeführt. Es ist kein Fehler aufgetreten, der weitere Informationen zum Problem enthält. Ich habe versucht, bei stackoverflow danach zu suchen, und habe diesen Link gefunden, der über ähnliche Problemaussagen spricht und aussieht, als ob ich vor einem ähnlichen Problem stehe, obwohl ich nicht sicher bin. Benötigen Sie etwas mehr Hilfe, um das Problem zu lösen.

Ich habe versucht, das Timeout für die FTP-Verbindung auf 60 Minuten einzustellen, jedoch weniger hilfreich. Vorher habe ich retrbinary () der ftplib verwendet, aber das gleiche Problem tritt dort auf. Ich habe versucht, verschiedene Blockgrößen und Fenstergrößen zu übergeben, aber damit war auch das Problem reproduzierbar.

Ich versuche, die Datei der Größe ~ 3 GB vom AWS EMR-Cluster herunterzuladen. Beispielcode ist unten geschrieben

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 

Eine weitere Option, die in der oben genannten Verknüpfung vorgeschlagen wird, besteht darin, den Verbindungsbeitrag zu schließen, indem ein kleiner Teil der Datei heruntergeladen wird, und dann die Verbindung neu zu starten. Kann jemand vorschlagen, wie dies erreicht werden kann, nicht sicher, wie der Download an der Stelle fortgesetzt werden kann, an der der Dateidownload zuletzt vor dem Schließen der Verbindung angehalten wurde. Ist diese Methode der vollständige Beweis für das Herunterladen der gesamten Datei?

Ich weiß nicht viel über Timeout-Einstellungen auf FTP-Server-Ebene und wusste nicht, was und wie es geändert werden muss. Grundsätzlich möchte ich einen generischen FTP-Downloader schreiben, der beim Herunterladen der Dateien von FTP / FTPS helfen kann.

Wenn ich die retrbinary () - Methode von ftplib verwende und den Debug-Level auf 2 setze.

ftp.set_debuglevel(2) 

Nachfolgende Protokolle werden gedruckt.

cmd 'TYPE I' setze 'TYPE I \ r \ n' get '200 Type auf I gesetzt. \ r \ n' bzw. '200 Type auf I gesetzt.' cmd 'PASV' setzt 'PASV \ r \ n' und erhält '227 Passive Mode (64,27,160,28,133,251). \ r \ n' bzw. '227 Passive Mode (64,27,160,28,133,251).' cmd 'r \ r \ r \ n \ r \ n \ r \ n \ r \ n \ r \ n \ r \ n \ r \ n \ r \ n \ r \ n \ r \' \ '' '' '' '' '' '' '' '' '' 'Anfrage' '' '' '' '' '' '' '' '' '' '' '' '' '.

Selbst wenn ich versuche, die Datei mithilfe des FTP-Clients auf dem Cluster-Client herunterzuladen, bleibt der Download nach Abschluss des Dateidownloads hängen, obwohl ich, wenn ich Expect und Settimeout im Shell-Skript verwende, das gewünschte Ergebnis erzielen kann.

Wie kann ich dasselbe im Python-Code erreichen?

1

0 Antworten auf die Frage