Python: extracción de archivos de un archivo zip grande (6GB +)

Tengo un script de Python donde necesito extraer el contenido de un archivo ZIP. Sin embargo, el archivo zip tiene más de 6 GB de tamaño.

Existe mucha información sobre los módulos zlib y zipfile , sin embargo, no puedo encontrar un solo enfoque que funcione en mi caso. Tengo el codigo

 with zipfile.ZipFile(fname, "r") as z: try: log.info("Extracting %s " %fname) head, tail = os.path.split(fname) z.extractall(folder + "/" + tail) except zipfile.BadZipfile: log.error("Bad Zip file") except zipfile.LargeZipFile: log.error("Zip file requires ZIP64 functionality but that has not been enabled (ie, too large)") except zipfile.error: log.error("Error decompressing ZIP file") 

Sé que necesito establecer el allowZip64 en true pero no estoy seguro de cómo hacerlo. Sin embargo, incluso tal como está, la excepción LargeZipFile no se lanza, sino la excepción BadZipFile . No tengo ni idea de porqué.

Además, ¿es este el mejor enfoque para manejar la extracción de un archivo zip de 6GB?

Actualización: modificando la excepción BadZipfile a esto:

     except zipfile.BadZipfile as inst: log.error("Bad Zip file") print type(inst) # the exception instance print inst.args # arguments stored in .args print inst 

    muestra:

      ('Bad magic number for file header',) 

    Actualización # 2:

    Los shows completos de rastreo.

     BadZipfile Traceback (most recent call last)  in () 6 for member in z.infolist(): 7 print member.filename[-70:], ----> 8 f = z.open(member, 'r') 9 size = 0 10 while True: /Users/brspurri/anaconda/python.app/Contents/lib/python2.7/zipfile.pyc in open(self, name, mode, pwd) 965 fheader = struct.unpack(structFileHeader, fheader) 966 if fheader[_FH_SIGNATURE] != stringFileHeader: --> 967 raise BadZipfile("Bad magic number for file header") 968 969 fname = zef_file.read(fheader[_FH_FILENAME_LENGTH]) BadZipfile: Bad magic number for file header 

    Ejecutando el código:

     import sys import zipfile with open(zip_filename, 'rb') as zf: z = zipfile.ZipFile(zf, allowZip64=True) z.testzip() doesn't output anything. 

    El problema es que tienes un archivo zip dañado. A continuación, puedo agregar más detalles sobre la corrupción, pero primero las cosas prácticas:

    Puede usar este fragmento de código para decirle qué miembro del archivo está dañado. Sin embargo, print z.testzip() ya te dirá lo mismo. Y zip -T o unzip en la línea de comandos también debe darle esa información con la verbosidad adecuada.


    Entonces, ¿qué haces al respecto?

    Bueno, obviamente, si puede obtener una copia no corrompida del archivo, haga eso.

    Si no es así, si solo desea omitir el archivo defectuoso y extraer todo lo demás, es bastante fácil, en su mayoría el mismo código que el fragmento de código vinculado anteriormente:

     with open(sys.argv[1], 'rb') as zf: z = zipfile.ZipFile(zf, allowZip64=True) for member in z.infolist(): try: z.extract(member) except zipfile.error as e: # log the error, the member.filename, whatever 

    El mensaje de excepción del Bad magic number for file header significa que el zipfile pudo abrir exitosamente el archivo zip, analizar su directorio, encontrar la información de un miembro, buscar a ese miembro dentro del archivo y leer el encabezado de ese miembro, todo lo cual significa que probablemente no tenga problemas relacionados con zip64 aquí. Sin embargo, cuando leyó ese encabezado, no tenía la firma “mágica” esperada de PK\003\004 . Eso significa que el archivo está dañado.

    El hecho de que la corrupción resulte exactamente en 4294967296 implica muy fuertemente que tuvo un problema de 64 bits en algún lugar de la cadena, porque eso es exactamente 2 ** 32.


    La herramienta de línea de comandos zip / unzip tiene algunas soluciones para lidiar con las causas comunes de la corrupción que llevan a problemas como este. Parece que esas soluciones pueden estar funcionando para este archivo, dado que recibes una advertencia, pero al parecer todos los archivos se recuperaron. La biblioteca de zipfile de Python no tiene esas soluciones, y dudo que quieras escribir tu propio código de manejo de archivos zip tú mismo …

    Sin embargo, eso abre la puerta a dos posibilidades más:

    Primero, zip podría ser capaz de reparar el archivo zip por usted, usando la -FF -F de -FF . (Lea la página de manual, o zip -h , o pregunte en un sitio como SuperUser si necesita ayuda con eso).

    Y si todo lo demás falla, puedes ejecutar la herramienta de unzip desde Python, en lugar de usar un zipfile , como esto:

     subprocess.check_output(['unzip', fname]) 

    Eso le da mucha menos flexibilidad y potencia que el módulo zipfile , por supuesto, pero de todos modos no está usando ninguna de esa flexibilidad; Sólo estás llamando a extractall .