2010-06-21 15 views
28

Tengo dos archivos zip, ambas de carácter bien con Windows Explorer y 7-zip.expediente es el resultado de descomprimir en "BadZipFile: El archivo no es un archivo zip"

Sin embargo, cuando los abro con el módulo zipfile de Python [zipfile.ZipFile ("filex.zip")], uno de ellos se abre pero el otro da error "BadZipfile: File is not a zip file".

Me he asegurado de que este último sea un archivo Zip válido abriéndolo con 7-Zip y mirando sus propiedades (dice 7Zip.ZIP). Cuando abro el archivo con un editor de texto, los primeros dos caracteres son "PK", mostrando que es de hecho un archivo zip.

estoy usando Python 2.5 y realmente no tienen ni idea de cómo ir sobre esto. Lo intenté tanto con Windows como con Ubuntu y existe un problema en ambas plataformas.

Actualización: Rastreo de Python 2.5.4 en Windows:

Traceback (most recent call last): 
File "<module1>", line 5, in <module> 
    zipfile.ZipFile("c:/temp/test.zip") 
File "C:\Python25\lib\zipfile.py", line 346, in init 
    self._GetContents() 
File "C:\Python25\lib\zipfile.py", line 366, in _GetContents 
    self._RealGetContents() 
File "C:\Python25\lib\zipfile.py", line 378, in _RealGetContents 
    raise BadZipfile, "File is not a zip file" 
BadZipfile: File is not a zip file 

Básicamente, cuando la función se llama _EndRecData para obtener datos de Fin de Directorio Central" registro, el pago y envío comentario longitud falla [endrec [ . 7] == len (comentario)]

los valores de los locales en la función _EndRecData son como siguiente:

END_BLOCK: 4096, 
comment: '\x00', 
data: '\xd6\xf6\x03\x00\x88,N8?<e\xf0q\xa8\x1cwK\x87\x0c(\x82a\xee\xc61N\'1qN\x0b\x16K-\x9d\xd57w\x0f\xa31n\xf3dN\x9e\xb1s\xffu\xd1\.....', (truncated) 
endrec: ['PK\x05\x06', 0, 0, 4, 4, 268, 199515, 0], 
filesize: 199806L, 
fpin: <open file 'c:/temp/test.zip', mode 'rb' at 0x045D4F98>, 
start: 4073 
+5

¿Podría ser esto: http://bugs.python.org/issue1757072? –

+0

Intenta ejecutar el comando 'archivo' de unix en tus archivos. Puede ser que te dará alguna pista. –

+0

Para ambos archivos dice: Datos de archivo Zip, al menos v2.0 para extraer – sharjeel

Respuesta

1

Muestra la trazabilidad completa que obtuviste de Python; esto puede dar una pista sobre cuál es el problema específico. Sin respuesta: ¿Qué software produjo el archivo incorrecto y en qué plataforma?

Actualización: El rastreo indica que tiene problemas para detectar el "Fin del Directorio Central de" registro en el archivo - véase función _EndRecData a partir de la línea 128 de C: \ Python25 \ Lib \ zipfile.py

Sugerencias:
(1) Traza través de la función
anterior (2) probarlo en la última Python
(3) Responder a la pregunta anterior.
(4) Leer this y todo lo encontrado por google("BadZipfile: File is not a zip file") que parece ser relevante

+0

de Windows, Python 2.5.2: Rastreo (llamada más reciente pasado): Archivo "", línea 5, en zipfile.ZipFile ("c: /temp/test.zip") archivo "C: \ Python25 \ lib \ zipfile.py "línea 346, en __init__ self._GetContents() archivo "C: \ Python25 \ lib \ zipfile.py", línea 366, en _GetContents self._RealGetContents() archivo" C: \ Python25 \ lib \ zipfile.py ", línea 378, en _RealGetContents raise BadZipfile," El archivo no es un archivo zip " BadZipfile: El archivo no es un archivo zip – sharjeel

+0

Aquí está la versión formateada de traceback: http: // dpaste.de/X0Pb/ – sharjeel

+0

Gracias para el enlace. Ya lo he pasado pero eso no ayudó. Probado en Python 2.5.4, 2.6.5 en Windows y Python 2.5.2 en Ubuntu de 64 bits. – sharjeel

-1

Ha intentado una pitón más reciente, o si eso es demasiado problema, simplemente una nueva zipfile.py? He utilizado con éxito una copia de zipfile.py de Python 2.6.2 (la última en ese momento) con Python 2.5 para abrir algunos archivos zip que no eran compatibles con el módulo de archivo zip de Py2.5.

+0

Sí, lo he probado con 2.6.5 también. El problema persiste :( – sharjeel

8

archivos de archivo con el nombre puede confundir pitón - tratar nombrarlo otra cosa. si TODAVÍA puedo trabajar, probar este código:

def fixBadZipfile(zipFile): 
f = open(zipFile, 'r+b') 
data = f.read() 
pos = data.find('\x50\x4b\x05\x06') # End of central directory signature 
if (pos > 0): 
    self._log("Trancating file at location " + str(pos + 22)+ ".") 
    f.seek(pos + 22) # size of 'ZIP end of central directory record' 
    f.truncate() 
    f.close() 
else: 
    # raise error, file is truncated 
4

me encuentro con el mismo problema. Mi problema era que era un gzip en lugar de un archivo zip. Cambié a la clase gzip.GzipFile y funcionó a las mil maravillas.

6

La solución de astronautlevel funciona en la mayoría de los casos, pero los datos comprimidos y los CRC en el Zip también pueden contener los mismos 4 bytes.Debería hacer un rfind (no find), buscar pos + 20 y luego agregar escribir \x00\x00 al final del archivo (indicar a las aplicaciones zip que la longitud de la sección 'comentarios' es de 0 bytes).


    # HACK: See http://bugs.python.org/issue10694 
    # The zip file generated is correct, but because of extra data after the 'central directory' section, 
    # Some version of python (and some zip applications) can't read the file. By removing the extra data, 
    # we ensure that all applications can read the zip without issue. 
    # The ZIP format: http://www.pkware.com/documents/APPNOTE/APPNOTE-6.3.0.TXT 
    # Finding the end of the central directory: 
    # http://stackoverflow.com/questions/8593904/how-to-find-the-position-of-central-directory-in-a-zip-file 
    # http://stackoverflow.com/questions/20276105/why-cant-python-execute-a-zip-archive-passed-via-stdin 
    #  This second link is only losely related, but echos the first, "processing a ZIP archive often requires backwards seeking" 
    content = zipFileContainer.read() 
    pos = content.rfind('\x50\x4b\x05\x06') # reverse find: this string of bytes is the end of the zip's central directory. 
    if pos>0: 
     zipFileContainer.seek(pos+20) # +20: see secion V.I in 'ZIP format' link above. 
     zipFileContainer.truncate() 
     zipFileContainer.write('\x00\x00') # Zip file comment length: 0 byte length; tell zip applications to stop reading. 
     zipFileContainer.seek(0) 

    return zipFileContainer
Cuestiones relacionadas