2016-05-27 14 views
11

Ich habe eine Textdatei von 25 GB. Also komprimierte ich es zu tar.gz und es wurde 450 MB. jetzt möchte ich diese Datei von Python lesen und die Textdaten verarbeiten. Dafür habe ich question verwiesen. aber in meinem Fall funktioniert Code nicht. der Code ist wie folgt:.tar.gz-Datei in Python lesen

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) 

die Fehler wie folgt:

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

auch, Gibt es eine andere Methode, um diese Aufgabe zu tun?

+1

So etwas wie http://stackoverflow.com/q/33113600/ 1240268 –

+1

* Wenn Mitglied keiner der oben genannten ist, wird keine zurückgegeben. *, Das Mitglied ist keine Datei oder Link. –

Antwort

14

Die docs sagen uns, dass Keine von extractfile() zurückgegeben wird, wenn das Mitglied eine nicht reguläre Datei oder Link ist.

Eine mögliche Lösung ist über die Keine Ergebnisse überspringen:

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() 
3

tarfile.extractfile() kann None zurück, wenn das Element weder eine Datei noch ein Link ist. Zum Beispiel könnte Ihr tar-Archiv Verzeichnisse oder Gerätedateien enthalten. Um dies zu beheben:

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) 
1

können Sie versuchen, diese einen

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 
+0

Danke für das Code-Snippet. Sie lesen jedoch zweimal - einmal beim Einstellen der Variable "data" und beim nächsten Mal beim Drucken. Können Sie Ihren Code ändern, um das zu beheben? –

+0

@SaurabhHirani Geändert. Danke für deine Erinnerung. – VICTOR

1

Sie können nicht „lesen“, um den Inhalt einiger speziellen Dateien wie Links noch tar unterstützt sie und tarfile wird sie in Ordnung extrahieren. Wenn tarfile sie extrahiert, gibt sie kein dateiähnliches Objekt zurück, sondern None. Und Sie erhalten einen Fehler, weil Ihr Tarball eine solche spezielle Datei enthält.

Ein Ansatz besteht darin, den Typ eines Eintrags in einem Tarball zu ermitteln, den Sie gerade verarbeiten, bevor Sie ihn extrahieren: Mit diesen Informationen können Sie entscheiden, ob Sie die Datei "lesen" können. Sie können dies erreichen, indem Sie tarfile.getmembers()tarfile.TarInfo s aufrufen, die detaillierte Informationen über den Dateityp enthalten, der im Tarball enthalten ist.

Die tarfile.TarInfo Klasse hat alle Attribute und Methoden, die Sie den Typ des Teers Mitglied bestimmen müssen, wie isfile() oder isdir() oder tinfo.islnk() oder tinfo.issym() und dann entsprechend entscheiden, was mit jedem Mitglied tun, um (Extrakt oder nicht, usw.).

Zum Beispiel verwende ich diese den Typ der Datei in this patched tarfile zu testen spezielle Dateien und Prozess-Links in besonderer Weise zu überspringen Extrahieren:

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