2016-06-10 15 views
1

Mein Ziel ist es, eine Datei aus einer .tar.gz Datei zu extrahieren, ohne auch die Unterverzeichnisse herauszuziehen, die der gewünschten Datei vorausgehen. Ich versuche, meine Methode von dieser question zu modulieren. Ich fragte bereits eine question von meiner eigenen, aber es schien, dass die Antwort, die ich dachte, funktionieren würde nicht vollständig funktionieren würde.Wie kann ich meine .tar.gz-Datei in ein dateiähnliches Objekt für shutil.copyfileobj umwandeln?

Kurz gesagt, shutil.copyfileobj kopiert nicht den Inhalt meiner Datei.

Mein Code ist jetzt:

import os 
import shutil 
import tarfile 
import gzip 

with tarfile.open('RTLog_20150425T152948.gz', 'r:*') as tar: 
    for member in tar.getmembers(): 
     filename = os.path.basename(member.name) 
     if not filename: 
      continue 

     source = tar.fileobj 
     target = open('out', "wb") 
     shutil.copyfileobj(source, target) 

dieser Code die Datei beim Laufen out erfolgreich jedoch erstellt wurde, die Datei leer war. Ich weiß, dass diese Datei, die ich extrahieren wollte, in der Tat viele Informationen hat (ungefähr 450 kb). A print(member.size) gibt 1564197 zurück.

Meine Versuche, das zu lösen, waren nicht erfolgreich. A print(type(tar.fileobj)) sagte mir, dass tar.fileobj ein <gzip _io.BufferedReader name='RTLog_20150425T152948.gz' 0x3669710> ist.

Deshalb habe ich versucht, source an veränderte: source = gzip.open(tar.fileobj) aber der folgende Fehler ausgelöst:

Traceback (most recent call last): 
    File "C:\Users\dzhao\Desktop\123456\444444\blah.py", line 15, in <module> 
    shutil.copyfileobj(source, target) 
    File "C:\Python34\lib\shutil.py", line 67, in copyfileobj 
    buf = fsrc.read(length) 
    File "C:\Python34\lib\gzip.py", line 365, in read 
    if not self._read(readsize): 
    File "C:\Python34\lib\gzip.py", line 433, in _read 
    if not self._read_gzip_header(): 
    File "C:\Python34\lib\gzip.py", line 297, in _read_gzip_header 
    raise OSError('Not a gzipped file') 
OSError: Not a gzipped file 

Warum Kopieren ist nicht shutil.copyfileobj tatsächlich den Inhalt der Datei im tar.gz?

+0

Sie die Größe Option in 'shutil.copyfileobj()' fehlen. Sie sollten "member.size" einschließen, sonst wird es bis zum Ende der TAR-Datei gelesen. Ich bezweifle, dass es Ihr tatsächliches Problem beheben wird, obwohl –

+0

@AlastairMcCormack Oh, ich habe nicht erkannt, dass es bis zum Ende der Tarfile gelesen. In diesem Fall ist es keine große Sache, denn das Tarfile ist nur eine Datei, aber danke! – Dzhao

Antwort

2

fileobj ist keine dokumentierte Eigenschaft von TarFile. Es ist wahrscheinlich ein internes Objekt, das verwendet wird, um die gesamte TAR-Datei darzustellen, nicht etwas, das für die aktuelle Datei spezifisch ist.

Verwenden TarFile.extractfile() ein dateiähnliche Objekt für ein bestimmtes Mitglied zu erhalten:

… 
source = tar.extractfile(member) 
target = open("out", "wb") 
shutil.copyfile(source, target) 
+0

'Extractfile()' extrahiert definitiv die Datei, aber ich bekomme die unordentlichen Unterordner vor der Datei. Ich möchte nur die Datei und nicht die darunter liegenden Unterverzeichnisse kopieren. – Dzhao

+0

Huh? Trotz des (irreführenden!) Namens extrahiert 'tar.extractfile()' nichts selbst. Es gibt nur ein dateiähnliches Objekt zurück. – duskwuff

+0

Ok Entschuldigung, ich verwechselte 'extractfile()' mit 'extract()' oder 'extractall()'. Ich habe deinen Code ausprobiert und es funktioniert. Während ich dachte, ich lese die Tarfile-Dokumente gut genug, habe ich eindeutig nicht. Vielen Dank! – Dzhao