wake-up-neo.com

Lesen Sie die .tar.gz-Datei in Python

Ich habe eine Textdatei von 25 GB. Also habe ich es in tar.gz komprimiert und es wurden 450 MB. Jetzt möchte ich diese Datei aus Python lesen und die Textdaten verarbeiten. Dafür habe ich question verwiesen. aber in meinem fall funktioniert der code nicht. Der Code lautet wie folgt: 

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)

der Fehler lautet wie folgt: 

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

gibt es auch eine andere Methode, um diese Aufgabe zu erledigen?

16
KrunalParmar

Die docs sagen uns, dass None von extractfile () zurückgegeben wird, wenn das Mitglied keine reguläre Datei oder Verknüpfung ist.

Eine mögliche Lösung ist das Überspringen der None Ergebnisse:

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() kann None zurückgeben, wenn das Mitglied weder eine Datei noch ein Link ist. Beispielsweise kann Ihr tar-Archiv Verzeichnisse oder Gerätedateien enthalten. Reparieren:

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

Sie können den Inhalt einiger spezieller Dateien (z. B. Links) nicht "lesen", aber tar unterstützt sie, und Tarfile wird sie gut extrahieren. Wenn tarfile sie extrahiert, gibt es kein dateiähnliches Objekt zurück, sondern None. Und Sie erhalten eine Fehlermeldung, weil Ihr Tarball eine solche spezielle Datei enthält.

Ein Ansatz besteht darin, den Typ eines Eintrags in einem Tarball zu bestimmen, den Sie vor dem Extrahieren bearbeiten: Mit diesen Informationen können Sie entscheiden, ob Sie die Datei "lesen" können oder nicht. Sie können dies erreichen, indem Sie tarfile.getmembers() Returns tarfile.TarInfos aufrufen, die detaillierte Informationen zum im Tarball enthaltenen Dateityp enthalten. 

Die Klasse tarfile.TarInfo verfügt über alle Attribute und Methoden, die Sie benötigen, um den Typ des tar-Elements zu bestimmen, wie z. B. isfile() oder isdir() oder tinfo.islnk() oder tinfo.issym(). Dann entscheiden Sie entsprechend, was mit jedem Member zu tun ist (extrahieren oder nicht usw.).

Zum Beispiel benutze ich diese, um den Dateityp in this patched tarfile zu testen, um das Extrahieren spezieller Dateien und Verarbeitungslinks auf eine spezielle Weise zu überspringen:

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

Sie können dies versuchen

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