9
votes

Zipfile ne peut pas gérer un type de données zip?

Je suis venu sur ce problème tout en essayant de décompresser un fichier zip.

- zipfile.is_zipfile (my_file) retourne toujours false, même si la commande UNIX UNZIP le gère tout simplement bien. En outre, lorsque vous essayez de faire zipfile.zipfile (chemin / fichier_handle_to_path) i obtenir la même erreur

- The Fichier Retourner les données Zip Archives, au moins v2.0 pour extraire et utiliser moins sur le fichier qu'il affiche:

pkzip pour iSeries par pkware Méthode de longueur Taille CMPR Date Time CRC-32 Nom 2113482674 DEFL: S 204502989 90% 2010-11-01 08:39 2CEE662E MYFILE.TXT 2113482674 204502989 90% 1 Fichier

Des idées Comment puis-je contourner ce problème? Ce serait bien que je puisse faire du travail zipfile de Python car j'ai déjà des tests unitaires que je devrai laisser tomber si je passerai à exécuter sous-processus.Call ("Unzip")


10 commentaires

Importer OS Et dites-nous, quel os.path.exists (my_file) retourne.


@eumiro: vrai. Pourquoi ? :) Merci!


@hyperborean - Je pensais juste que vous pourriez avoir un problème avec le nom de fichier, car zipfile.is_zipfile renvoie false pour des fichiers non existants aussi.


On dirait que vous pourriez avoir un problème similaire à Stackoverflow.com/questions/3083235 / Problème avec-unzipping-f Île . Malheureusement, cette affiche n'a pas reçu de solution. :(


Quel est le fichier de fichiers, plus de 1 Go?


Pourrait-il s'agir de cela: bugs.python.org/issue1757072 ?


@Paulo Scardine: Decompressé, c'est 2 Go. Compressé c'est 196 Mo.


Vous pensiez que "Iseries" n'avait pas besoin de plus qu'une référence occasionnelle? Exécutez-vous dans une partition Linux (avec quelle version de Python?) Ou sous OS / 400?


@ John Machin: Python2.6 (2.6.2-2.6.6) Ils agissent tous les mêmes. Courir sur des machines Linux. Merci!


@hyperborean: Pourriez-vous poster un zip démontrant ce problème quelque part? Avec certaines données à tester, il pourrait être plus facile d'identifier le problème réel.


3 Réponses :


1
votes

Vous dites en utilisant moins code> sur le fichier qu'il affiche telle et telle. Voulez-vous dire cela?

less my_file


0 commentaires

7
votes

Concentrez-vous dans le même problème sur mes fichiers et a été capable de le résoudre. Je ne sais pas comment ils ont été générés, comme dans l'exemple ci-dessus. Ils avaient tous eu des données de fuite à la fin ignorés par les deux fenêtres de 7z et l'échec de la zipfile de Python de Python.

Ceci est le code pour résoudre le problème: P>

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("Truncating 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  


2 commentaires

Je ne sais pas si t sa version de la version Python, mais j'ai eu TypeError: l'argument doit être un objet entier ou d'octets, non "STR 'Ceci est résolu en remplaçant tout dans la parenthèse derrière" data.find "avec b' \ x50 \ x4b \ x05 \ x06 '


idem @ morph3us, avez-vous fini par trouver une solution?



0
votes
# Utilize mmap module to avoid a potential DoS exploit (e.g. by reading the
# whole zip file into memory). A bad zip file example can be found here:
# https://bugs.python.org/issue24621

import mmap
from io import UnsupportedOperation
from zipfile import BadZipfile

# The end of central directory signature
CENTRAL_DIRECTORY_SIGNATURE = b'\x50\x4b\x05\x06'


def repair_central_directory(zipFile):
    if hasattr(zipFile, 'read'):
        # This is a file-like object
        f = zipFile
        try:
            fileno = f.fileno()
        except UnsupportedOperation:
            # This is an io.BytesIO instance which lacks a backing file.
            fileno = None
    else:
        # Otherwise, open the file with binary mode
        f = open(zipFile, 'rb+')
        fileno = f.fileno()
    if fileno is None:
        # Without a fileno, we can only read and search the whole string
        # for the end of central directory signature.
        f.seek(0)
        pos = f.read().find(CENTRAL_DIRECTORY_SIGNATURE)
    else:
        # Instead of reading the entire file into memory, memory-mapped the
        # file, then search it for the end of central directory signature.
        # Reference: https://stackoverflow.com/a/21844624/2293304
        mm = mmap.mmap(fileno, 0)
        pos = mm.find(CENTRAL_DIRECTORY_SIGNATURE)
        mm.close()
    if pos > -1:
        # size of 'ZIP end of central directory record'
        f.truncate(pos + 22)
        f.seek(0)
        return f
    else:
        # Raise an error to make it fail fast
        raise BadZipfile('File is not a zip file')

0 commentaires