2017-01-26 6 views
0

Backstory ist im Versuch, einige Daten aus einem FTP-Login, die ich erhielt, zu ziehen. Diese Daten werden täglich aktualisiert, und ich glaube, sie löschen das FTP am Ende jeder Woche oder jeden Monats. Ich habe darüber nachgedacht, ein Datum einzugeben und das Skript täglich auszuführen, um zu sehen, ob es Dateien gibt, die mit dem Datum übereinstimmen, aber wenn die Serverzeit nicht genau ist, kann es zu Datenverlust kommen. Für den Moment möchte ich nur ALLE Dateien herunterladen und dann an der Feinabstimmung arbeiten.ftplib - Python: Skript hängt beim Herunterladen von großen Dateien

Ich habe nicht viel mit dem Kodieren von ftp gearbeitet, aber scheint einfach genug. Das Problem, das ich habe, ist jedoch, dass kleine Dateien ohne Probleme heruntergeladen werden und ihre Dateigrößen geprüft werden. Wenn es versucht, eine große Datei herunterzuladen, die normalerweise ein paar Minuten dauern würde, wird es zu einem bestimmten Punkt (fast die Datei wird abgeschlossen) und dann stoppt es einfach und das Skript hängt.

Beispiel:

Es wird versucht, eine Datei herunterzuladen, die 373.485.927 Bytes groß ist. Das Skript wird ausgeführt und lädt diese Datei bis zu 373485568 Byte herunter. Es stoppt IMMER bei diesem Betrag, nachdem Sie verschiedene Methoden ausprobiert und einen Code geändert haben.

Versteh nicht, warum es immer an diesem Byte stoppt und warum es mit kleineren Dateien (1000 Bytes und darunter) gut funktionieren würde.

import os 
import sys 
import base64 
import ftplib 

def get_files(ftp, filelist): 
    for f in filelist: 
     try: 
      print "Downloading file " + f + "\n" 
      local_file = os.path.join('.', f) 
      file = open(local_file, "wb") 
      ftp.retrbinary('RETR ' + f, file.write) 
     except ftplib.all_errors, e: 
      print str(e) 

     file.close() 
    ftp.quit() 

def list_files(ftp): 
    print "Getting directory listing...\n" 
    ftp.dir() 
    filelist = ftp.nlst() 
    #determine new files to DL, pass to get_files() 
    #for now we will download all each execute 
    get_files(ftp, filelist) 

def get_conn(host,user,passwd): 
    ftp = ftplib.FTP() 
    try: 
     print "\nConnecting to " + host + "...\n" 
     ftp.connect(host, 21) 
    except ftplib.all_errors, e: 
     print str(e) 

    try: 
     print "Logging in...\n" 
     ftp.login(user, base64.b64decode(passwd)) 
    except ftplib.all_errors, e: 
     print str(e) 

    ftp.set_pasv(True) 

    list_files(ftp) 

def main(): 
    host = "host.domain.com" 
    user = "admin" 
    passwd = "base64passwd" 

    get_conn(host,user,passwd) 

if __name__ == '__main__': 
    main() 

Die Ausgabe sieht so aus, dass die Datei dddd.tar.gz die große ist und sie nie beendet.

Download-Datei aaaa.del.gz

Datei Herunterladen bbbb.del.gz

Datei Herunterladen cccc.del.gz

Download-Datei dddd.tar.gz

+0

Klingt wie eine Pufferung Problem. Die Größe ist Stopps bei einem Vielfachen von 4096, was ein sehr wahrscheinlicher Wert für einen Puffer ist. Interessanterweise ist der Standardpuffer von rebbinary 8192 und die Größe, bei der er stoppt, ist ** nicht ** ein Vielfaches von 8192, also ist dieser Puffer nicht der Fehler. – spectras

+0

Als Nebenbemerkung ist 'Datei' ein reserviertes Wort in Python. Sie sollten es nicht als Variablennamen verwenden. Benennen Sie es beispielsweise in "fd" um (für "file descriptor"). Ich bezweifle, dass es hier das Problem verursacht, aber Sie sollten diese Möglichkeit zuerst beseitigen. – spectras

+0

Übrigens, das Problem könnte auf der Remote-Seite sein, zum Beispiel, dass der FTP-Server am Ende nicht richtig gelöscht wird - welchen FTP-Server benutzen Sie? Und hast du mit einem anderen getestet? – spectras

Antwort

0

Dies könnte verursacht durch ein Timeout Problem, vielleicht versuchen in:

def get_conn(host,user,passwd): 
    ftp = ftplib.FTP() 

in größeren Timeouts hinzufügen, bis Sie eher eine Idee haben, was los ist, wie:

def get_conn(host,user,passwd): 
    ftp = ftplib.FTP(timeout=100) 

Ich bin mir nicht sicher, ob ftplib standardmäßig ein Timeout oder nicht, würde es sich lohnen, die Überprüfung und lohnt, wenn Sie Zeitüberschreitung vom Server. Hoffe das hilft.

+0

Danke, ich werde das versuchen. In der Dokumentation wird angegeben, dass das globale Standardzeitlimit verwendet wird. Ich nehme das an .. >>> import socket >>> print socket.getdefaulttimeout() >>> None – DeNi

+0

Das Setzen eines hohen Timeouts hat nicht funktioniert. Ich downloade nur noch einmal am selben Byte. Ich werde nie vom Server getrennt, daher glaube ich nicht, dass es jemals ein Timeout-Problem gab. – DeNi

+0

Es ist ganz sicher ** nicht ** ein Timeout-Problem. Die Wahrscheinlichkeit, dass es bei einem perfekten Vielfachen von 4096, der häufigsten Seitengröße, bricht, ist wirklich gering. – spectras

0

Wenn Sie Ihre scrpit in Windows cmd-Konsole ausgeführt wird, versuchen Sie die "QuickEdit-Modus" Option von cmd zu deaktivieren.

Ich hatte ein Problem, dass mein FTP-Skript in Windows läuft hängt, aber funktioniert normalerweise in Linux. Endlich fand ich, dass diese Lösung für mich funktioniert.

Ref: enter link description here

Verwandte Themen