web-dev-qa-db-fra.com

Lire le fichier .tar.gz en Python

J'ai un fichier texte de 25 Go. donc je l'ai compressé en tar.gz et il est devenu 450 MB. Maintenant, je veux lire ce fichier à partir de python et traiter les données textuelles. Pour cela, je me suis référé question . mais dans mon cas, le code ne fonctionne pas. Le code est comme suit : 

import tarfile
import numpy as np 

tar = tarfile.open("filename.tar.gz", "r:gz")
for member in tar.getmembers():
     f=tar.extractfile(member)
     content = f.read()
     Data = np.loadtxt(content)

l'erreur est la suivante: 

Traceback (most recent call last):
  File "dataExtPlot.py", line 21, in <module>
    content = f.read()
AttributeError: 'NoneType' object has no attribute 'read'

aussi, y at-il une autre méthode pour faire cette tâche?

16
KrunalParmar

Les docs nous indiquent que None est renvoyé par extractfile () si le membre n'est pas un fichier ou un lien normal.

Une solution possible consiste à ignorer les résultats Aucun:

tar = tarfile.open("filename.tar.gz", "r:gz")
for member in tar.getmembers():
     f = tar.extractfile(member)
     if f is not None:
         content = f.read()
20

tarfile.extractfile() peut retourner None si le membre n'est ni un fichier ni un lien. Par exemple, votre archive tar peut contenir des répertoires ou des fichiers de périphérique. Pour réparer:

import tarfile
import numpy as np 

tar = tarfile.open("filename.tar.gz", "r:gz")
for member in tar.getmembers():
     f = tar.extractfile(member)
     if f:
         content = f.read()
         Data = np.loadtxt(content)
4
mhawke

Vous ne pouvez pas "lire" le contenu de certains fichiers spéciaux tels que des liens, mais tar les prend en charge et tarfile les extraira correctement. Lorsque tarfile les extrait, il ne retourne pas un objet de type fichier mais aucun. Et vous obtenez une erreur car votre archive contient un tel fichier spécial.

Une approche consiste à déterminer le type d'une entrée dans une archive que vous traitez avant de l'extraire: avec ces informations, vous pouvez décider si vous pouvez ou non "lire" le fichier. Pour ce faire, appelez tarfile.getmembers() et renvoie tarfile.TarInfos contenant des informations détaillées sur le type de fichier contenu dans l'archive. 

La classe tarfile.TarInfo contient tous les attributs et méthodes dont vous avez besoin pour déterminer le type de membre tar, tel que isfile() ou isdir() ou tinfo.islnk() ou tinfo.issym(), puis décide en conséquence de ce qu'il faut faire avec chaque membre (extrait ou non, etc.).

Par exemple, je les utilise pour tester le type de fichier dans ce fichier compressé pour ignorer l'extraction de fichiers spéciaux et les liens de processus d'une manière particulière:

for tinfo in tar.getmembers():
    is_special = not (tinfo.isfile() or tinfo.isdir()
                      or tinfo.islnk() or tinfo.issym())
...
1

Vous pouvez essayer celui-ci

t = tarfile.open("filename.gz", "r")
for filename in t.getnames():
    try:
        f = t.extractfile(filename)
        Data = f.read()
        print filename, ':', Data
    except :
        print 'ERROR: Did not find %s in tar archive' % filename
1
VICTOR