Gibt es einen besonderen Trick, um eine ZIP-Datei herunterladen und auf der Festplatte mit Python zu schreiben?

StackOverflow https://stackoverflow.com/questions/576238

  •  05-09-2019
  •  | 
  •  

Frage

Ich bin FTPing eine Zip-Datei von einer entfernten FTP-Site Pythons ftplib verwenden. Ich versuche es dann auf der Festplatte zu schreiben. Die Dateischreibarbeiten, aber die meisten Versuche, die Zip zu öffnen, mit WinZip oder WinRar scheitern; Beide Anwendungen behaupten, dass die Datei beschädigt ist. Seltsamer jedoch beim Rechtsklick und versuchen, die Datei mit WinRar zu extrahieren, um die Datei wird Extrakt.

So klar zu sein, wird die Datei Schreib arbeiten, aber nicht open in den beliebten Zip-Apps, aber wird dekomprimieren die gleichen Apps verwenden. Beachten Sie, dass der Python zipfile Modul nie nicht die Reißverschluss zu extrahieren.

Hier ist der Code, den ich verwende die Zip-Datei vom FTP-Site zu erhalten (bitte das schlechte tabbing ignorieren, das ist nicht das Thema).

filedata = None
def appender(chunk):
    global filedata
    filedata += chunk


def getfile(filename):
  try:
      ftp = None

      try:
          ftp = FTP(address)
          ftp.login('user', 'password')

      except Exception, e:
          print e

      command = 'RETR ' + filename

      idx = filename.rfind('/')
      path = filename[0:idx]
      ftp.cwd(path)
      fileonly = filename[idx+1:len(filename)]

      ftp.retrbinary('RETR ' + filename, appender)

      global filedata
      data = filedata

      ftp.close()

      filedata = ''
      return data

  except Exception, e:
      print e

data = getfile('/archives/myfile.zip')    
file = open(pathtoNTFileShare, 'wb')
file.write(data)
file.close()
War es hilfreich?

Lösung

Pass file.write direkt in der retrbinary Funktion statt appender übergeben. Dies funktioniert, und es wird auch nicht so viel RAM verwenden, wenn Sie eine große Datei herunterladen.

Wenn Sie die Daten in einer Variable gespeichert obwohl mögen, können Sie auch eine Variable mit dem Namen:

blocks = []

Dann passieren statt appender retrbinary:

blocks.append

Ihre aktuelle appender Funktion ist falsch. + = Wird nicht korrekt funktionieren, wenn binäre Daten, weil sie versuchen, einen String Append zu tun und an der ersten NULL sieht stoppt es.

Wie @Lee B erwähnt können Sie auch urllib2 oder Locken verwenden. Aber Ihr aktueller Code ist fast richtig, wenn Sie die kleinen Änderungen vornehmen ich oben erwähnt.

Andere Tipps

Ich habe noch nie verwendet die Bibliothek, aber urllib2 funktioniert gut, und ist einfacher. Locke ist noch besser.

auf dem Code der Suche, kann ich ein paar Dinge falsch sehen. Ihre Ausnahme fängt nur die Ausnahme druckt, dann weiter. Für schwerwiegende Fehler wie nicht eine FTP-Verbindung bekommen, die sie benötigen, um die Nachricht und beenden Sie dann zu drucken. Außerdem beginnt Ihr FILEDATA als None aus, dann appender verwendet + = derjenigen hinzufügen, so dass Sie versuchen, eine Zeichenfolge + Keine anhängen, das eine Typeerror gibt, wenn ich es hier versuchen. Ich bin überrascht, es ist überhaupt arbeiten; Ich hätte gedacht, dass die appender eine Ausnahme auslösen würde, und so die FTP-Kopie würde zunichte machen.

Während Lesen wieder, ich habe gerade bemerkt, eine andere Antwort über die Verwendung von + = auf Binärdaten. Das könnte gut sein, es; Python versucht manchmal klug zu sein, und könnte „helfen“, wenn Sie Zeichenfolgen mit Leerzeichen oder NULs in ihnen, oder so etwas kommen. Ihre beste Wette ist die Datei geöffnet haben (nennen wir es outfile), und verwenden Sie Ihre appender nur outfile.write (Brocken).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top