2013-12-17 8 views
20

Ich versuche, das Python GZIP-Modul zu verwenden, um einfach mehrere .gz-Dateien in einem Verzeichnis zu dekomprimieren. Beachten Sie, dass ich die Dateien nicht lesen, sondern nur dekomprimieren möchte. Nach der Suche dieser Seite für eine Weile habe ich dieses Code-Segment, aber es funktioniert nicht:Verwenden von GZIP-Modul mit Python

import gzip 
import glob 
import os 
for file in glob.glob(PATH_TO_FILE + "/*.gz"): 
    #print file 
    if os.path.isdir(file) == False: 
     shutil.copy(file, FILE_DIR) 
     # uncompress the file 
     inF = gzip.open(file, 'rb') 
     s = inF.read() 
     inF.close() 

die GZ-Dateien in der richtigen Position sind, und ich kann den vollständigen Pfad + Dateinamen mit dem Druckbefehl drucken , aber das GZIP-Modul wird nicht ordnungsgemäß ausgeführt. Was vermisse ich?

+0

Ist die Datei in Ordnung? Du zeigst nicht, was nicht passiert. –

+0

Ja, die Datei ist in Ordnung. Ich kann die Datei mit Gunzip in der UNIX-Befehlszeile dekomprimieren. – user3111358

Antwort

37

Wenn Sie keinen Fehler erhalten, wird das GZip-Modul ordnungsgemäß ausgeführt.

Ich will nicht, um die Dateien zu lesen, dekomprimieren sie nur

Das gzip Modul nicht als Desktop-Archivierungsprogramm wie 7-zip funktioniert - man kann nicht „Dekomprimieren“ eine Datei ohne es zu "lesen". Was Sie wahrscheinlich unter "Dekomprimieren" verstehen, wird genauer beschrieben - aus Sicht der Programmierung - als "lese einen Stream aus einer komprimierten Datei und schreibe ihn in eine neue Datei".

inF = gzip.open(file, 'rb') 
s = inF.read() 
inF.close() 

Hier lesen Sie gerade den Stream. Sie müssen es nur in eine neue Datei schreiben:

inF = gzip.open(file, 'rb') 
outF = open(outfilename, 'wb') 
outF.write(inF.read()) 
inF.close() 
outF.close() 
+0

Kein Fehler tritt auf, wenn ich das Python-Skript ausführen, aber die Gzip-Datei ist nicht dekomprimiert. Ich möchte die Datei nur dekomprimieren, damit sie von einem anderen Tool verwendet werden kann, nicht in eine Datei geschrieben oder anderweitig in meinem Skript verwendet wird. – user3111358

+1

@ user3111358 Was bedeutet, * genau * durch "die gzip-Datei ist nicht unkomprimiert"? Was sagst du dazu? Hast du den Inhalt von 's' in deinem Code überprüft? – goncalopp

+0

Was ich meine ist die Gzip-Datei ist nicht unkomprimiert, was ich versuche zu tun. Ich möchte nur dekomprimieren, sonst nichts. – user3111358

5

Sie Datei in s Variable sind Dekomprimieren und nichts zu tun mit ihm. Sie sollten mit der Suche nach stackoverflow aufhören und mindestens Python-Tutorial lesen. Ernst.

Wie dem auch sei, es gibt einige, was falsch mit Ihrem Code:

  1. Sie brauchen, ist die entpackten Daten in s in eine Datei zu speichern.

  2. Es ist nicht notwendig, die tatsächlichen *.gz Dateien zu kopieren. Weil Sie in Ihrem Code die ursprüngliche gzip-Datei und nicht die Kopie entpacken.

  3. Sie verwenden file, die ein reserviertes Wort ist, als Variable. Dies ist kein ein Fehler, nur eine sehr schlechte Praxis.

Dies sollte wohl tun, was man wollte:

import gzip 
import glob 
import os 
import os.path 

for gzip_path in glob.glob(PATH_TO_FILE + "/*.gz"): 
    if os.path.isdir(gzip_path) == False: 
     inF = gzip.open(gzip_path, 'rb') 
     # uncompress the gzip_path INTO THE 's' variable 
     s = inF.read() 
     inF.close() 

     # get gzip filename (without directories) 
     gzip_fname = os.path.basename(gzip_path) 
     # get original filename (remove 3 characters from the end: ".gz") 
     fname = gzip_fname[:-3] 
     uncompressed_path = os.path.join(FILE_DIR, fname) 

     # store uncompressed file data from 's' variable 
     open(uncompressed_path, 'w').write(s) 
+0

Wenn Sie 'open (uncompressed_path, 'w'). Write (s)' aufrufen, ohne den Dateihandler einer Variablen zuzuweisen, brauchen Sie den Dateihandler nicht zu schließen. – Ander

+1

@Ander - Ja, weil das (anonyme) Dateiobjekt niemals einer Variablen zugewiesen wird und daher sofort nach der Ausführung zerstört wird. Ich finde es viel sauberer für einfache "write xy to file" oder "read from file" - das ist, wenn _exactly_ man lesen oder schreiben. Aber wenn Sie mehr als einen Lese-/Schreibvorgang durchführen, sollten Sie immer '' open (...) verwenden: ' –

4

ich in der Lage war, dieses Problem zu lösen, indem die Subprozess-Modul:

for file in glob.glob(PATH_TO_FILE + "/*.gz"): 
    if os.path.isdir(file) == False: 
     shutil.copy(file, FILE_DIR) 
     # uncompress the file 
     subprocess.call(["gunzip", FILE_DIR + "/" + os.path.basename(file)]) 

Da mein Ziel war einfach zu dekomprimieren die archivieren, erreicht der obige Code dies. Die archivierten Dateien befinden sich an einem zentralen Ort und werden unkomprimiert in einen Arbeitsbereich kopiert und in einem Testfall verwendet. Das GZIP-Modul war zu kompliziert für das, was ich erreichen wollte.

Danke für die Hilfe aller. Es ist sehr geschätzt!

6

Sie sollten with verwenden, um Dateien zu öffnen und natürlich das Ergebnis des Lesens der komprimierten Datei zu speichern.Siehe gzip documentation:

import gzip 
import glob 
import os 
import os.path 

for gzip_path in glob.glob("%s/*.gz" % PATH_TO_FILE): 
    if not os.path.isdir(gzip_path): 
     with gzip.open(gzip_path, 'rb') as in_file: 
      s = in_file.read() 

     # Now store the uncompressed data 
     path_to_store = gzip_fname[:-3] # remove the '.gz' from the filename 

     # store uncompressed file data from 's' variable 
     with open(path_to_store, 'w') as f: 
      f.write(s) 

Je nachdem, was genau wollen Sie tun, Sie vielleicht einen Blick auf tarfile und seine 'r:gz' Option zum Öffnen von Dateien haben wollen.

+0

Es wäre schöner,' os.path.splitext (gzip_fname) [0] 'zu verwenden, um' 'zu entfernen .gz' Erweiterung –

+0

Ihr Beispiel ist falsch, 'gzip_fname' existiert nicht, Sie müssen es in' gzip_path' ändern. Außerdem ist das, was Sie in 'gzip_path' bekommen, kein Pfad, sondern die gz-Datei. Daher sollten Sie 'os.path.isdir' in' os.path.isfile' ändern. Ich denke auch, dass die Verwendung von @gotson-Lösung schöner ist. –

0

Ich denke, es gibt eine viel einfachere Lösung als die anderen die op gegeben präsentierten nur alle Dateien in einem Verzeichnis extrahieren wollte:

import glob 
from setuptools import archive_util 

for fn in glob.glob('*.gz'): 
    archive_util.unpack_archive(fn, '.') 
+2

Archive_util.unpack_archive scheint .gz nicht zu unterstützen. Die Fehlermeldung lautet "setuptools.archive_util.UnrecognizedFormat: Nicht ein erkannter Archivtyp: K: \ z_temp \ file.gz". Auch shuthil.upack_archive unterstützt .gz nicht. Um die unterstützten Dateitypen für shutil_unpack_archive zu sehen: 'import shutil; print (shutil.get_archive_formats()) ' – punchcard

Verwandte Themen