¿Hay un truco especial para la descarga de un archivo zip y la escritura en el disco con Python?

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

  •  05-09-2019
  •  | 
  •  

Pregunta

Estoy FTPing un archivo zip desde un sitio FTP remoto usando ftplib de Python. entonces intentará escribir en el disco. Los trabajos de escritura de archivos, sin embargo la mayoría intentos de abrir el zip con WinZip o WinRAR fallan; ambas aplicaciones afirman que el archivo está dañado. Sin embargo Curiosamente, cuando hacen clic derecho y tratar de extraer el archivo con WinRAR, el archivo extracto.

Así que para que quede claro, el archivo de escritura va a funcionar, pero no lo hará Abrir dentro de las aplicaciones populares zip, pero descomprimir usando las mismas aplicaciones. Tenga en cuenta que el módulo Python archivo zip no no puede extraer las cremalleras.

Este es el código que estoy usando para obtener el archivo zip desde el sitio FTP (por favor, ignora el mal de tabulación, esa no es la cuestión).

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()
¿Fue útil?

Solución

Pase file.write directamente dentro de la función retrbinary en lugar de pasar appender. Esto funcionará y también no utilizará esa cantidad de RAM cuando se está descargando un archivo grande.

Si desea los datos almacenados en una variable, sin embargo, también puede tener una variable llamada:

blocks = []

A continuación, pasar a retrbinary en lugar de appender:

blocks.append

Su función appender actual es incorrecta. + = No funcionará correctamente si hay datos binarios porque va a tratar de hacer una Cadena sufijo y parar en el primer NULL que ve.

Según lo mencionado por @Lee B también se puede utilizar urllib2 o Curl. Sin embargo, su código actual es casi correcta si haces las pequeñas modificaciones que he mencionado anteriormente.

Otros consejos

Nunca he usado esa biblioteca, pero urllib2 funciona bien, y es más sencillo. La curvatura es aún mejor.

En cuanto a su código, puedo ver un par de cosas mal. Su captura excepción sólo imprime la excepción, y luego continúa. Para los errores fatales como no conseguir una conexión FTP, que necesitan para imprimir el mensaje y luego salir. Además, su filedata comienza como ninguno, entonces su appender utiliza + = añadir a eso, por lo que está tratando de añadir una cadena + Ninguna, lo que da un TypeError cuando intento aquí. Me sorprende que está funcionando en absoluto; Me hubiera adivinado que el appender sería una excepción, por lo que la copia FTP abortaría.

Mientras re-lectura, me he dado cuenta de otra respuesta sobre el uso de + = en datos binarios. Que bien podría ser él; pitón trata de ser inteligente a veces, y se podría "ayudar" cuando se une a las cadenas con espacios en blanco o NULs en ellos, o algo por el estilo. Su mejor opción que hay que tener el archivo abierto (vamos a llamarlo archivo de salida), y usar su appender sólo outfile.write (fragmento).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top