2016-05-27 76 views
11

Ho un file di testo di 25 GB. così l'ho compresso in tar.gz ed è diventato 450 MB. ora voglio leggere quel file da python ed elaborare i dati di testo. Per questo ho fatto riferimento a question. ma nel mio caso il codice non funziona. il codice è il seguente:Leggi il file .tar.gz in Python

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'errore è la seguente:

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

anche, C'è qualche altro metodo per fare questo compito?

+1

Qualcosa di simile http://stackoverflow.com/q/33113600/ 1240268 –

+1

* Se il membro non corrisponde a quanto sopra, viene restituito None. *, Il membro non è un file o un collegamento. –

risposta

14

Il docs ci dicono che Nessuno viene restituito da extractfile() se il membro di una non è un file regolare o un link.

Una possibile soluzione è quella di saltare il Nessuno risultati:

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() può restituire None se il membro non è né un file, né un collegamento. Ad esempio il tuo archivio tar potrebbe contenere directory o file di dispositivo. Per risolvere il problema:

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

Si può provare questo

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

Grazie per lo snippet di codice. Stai leggendo due volte però - una volta in impostazione della variabile "data" e la prossima volta in stampa. Puoi cambiare il tuo codice per risolverlo? –

+0

@SaurabhHirani modificato. Grazie per avermelo ricordato. – VICTOR

1

Non si può "leggere" il contenuto di alcuni file speciali come ad esempio i collegamenti ancora di catrame li sostiene e tarfile estrarrà loro bene. Quando vengono estratti da tarfile, non viene restituito un oggetto simile a un file, ma Nessuno. E ricevi un errore perché il tuo tarball contiene un file così speciale.

Un approccio è determinare il tipo di una voce in un archivio fisso che si sta elaborando prima di estrarlo: con queste informazioni a portata di mano è possibile decidere se è possibile "leggere" il file. È possibile ottenere questo chiamando tarfile.getmembers() restituisce tarfile.TarInfo s che contengono informazioni dettagliate sul tipo di file contenuto nel tarball.

La classe tarfile.TarInfo ha tutti gli attributi e metodi necessari per determinare il tipo di elemento di catrame come isfile() o isdir() o tinfo.islnk() o tinfo.issym() e quindi di conseguenza decidere cosa fare per ogni membro (estratto o no, ecc).

Per esempio ho utilizzare questi per verificare il tipo di file in this patched tarfile per saltare l'estrazione dei file speciali e collegamenti di processo in un modo speciale:

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