Weitere aktuelle Java-Titel finden Sie bei dpunkt.
 Inhaltsverzeichnis   Auf Ebene Zurück   Seite Zurück   Seite Vor   Auf Ebene Vor   Eine Ebene höher   Index


10.6.1

Komprimierung im GZIP-Format



Für die Komprimierung bzw. Dekomprimierung von Daten im GZIP-Format werden die Klassen GZIPOutputStream bzw. GZIPInputStream benötigt. Die Verwendung dieser Klassen wird im folgenden an einer Java-Implementierung der Unix-Utilities gzip und gunzip erläutert. gzip und gunzip werden für die Komprimierung bzw. Dekomprimierung von Dateien im GZIP-Format verwendet. Der Aufbau des GZIP-Formats kann in RFC 1952 nachgelesen werden. gzip ermöglicht die Komprimierung von genau einer Datei. Komprimierte Dateiarchive können mit gzip alleine nicht erstellt werden. Hierzu benötigt man zusätzlich ein Archivierungsprogramm, wie z. B. tar.

Die hier vorgestellten Implementierungen sind den Originalprogrammen in der Funktionalität allerdings nicht ganz ebenbürtig, da die vielen Kommandozeilenoptionen von gzip bzw. gunzip bei der Implementierung nicht berücksichtigt wurden. Ein Aufruf von der gzip-Reimplementierung komprimiert die übergebenen Dateien und ein Aufruf der gunzip-Reimplementierung nimmt eine Dekomprimierung der übergebenen Dateien vor. Weitere Funktionen werden in diesem Beispiel nicht implementiert.

gzip

Zunächst zur Reimplementierung des gzip-Kommandos. Das Listing des Programms ist relativ kurz:
  import java.util.zip.*;
  import java.io.*;
  
  public class Gzip {
  
    public static void main(String args[]) {
      int read = 0;
      byte[] data = new byte[1024];
      // Jeden übergebenen Dateinamen bearbeiten
      for (int i=0; i < args.length; i++) {
        try {
          // Original-Datei mit Stream verbinden
          File f = new File(args[i]);
          FileInputStream in = new FileInputStream(f);
          // Ausgabedatei erstellen
          GZIPOutputStream out =
            new GZIPOutputStream(
              new FileOutputStream(args[i]+".gz"));
          // Alle Daten der Original-Datei in die Ausgabedatei schreiben
          while((read = in.read(data, 0, 1024)) != -1)
            out.write(data, 0, read);
          in.close();
          out.close();
          f.delete();   // Original-Datei löschen
        }
        catch(Exception e) {
          e.printStackTrace();
        }
      }
    }
  
  }
Dem Programm werden per Kommandozeile beliebig viele Dateinamen übergeben. Innerhalb des Programms werden die Dateien im GZIP-Format komprimiert und die Ausgabe in eine Datei, deren Namen sich aus dem Namen der Originaldatei und der Endung gz zusammensetzt, geschrieben. Nach erfolgreicher Komprimierung wird anschließend die Originaldatei gelöscht.

In einer Schleife werden im Programm alle übergebenen Dateinamen verarbeitet. Zunächst wird für die aktuell bearbeitete Datei ein FileInputStream angelegt, über den die Daten eingelesen werden. Dies geschieht in diesem Beispiel über ein File-Objekt, da man dadurch die Eingabedatei nach Durchführung der Komprimierung einfach löschen kann.

Für die Ausgabe wird ein GZIPOutputStream erzeugt, über den die Komprimierung erfolgt. Der Konstruktor von GZIPOutputStream erwartet einen OutputStream als Parameter. In den übergebenen Stream werden schließlich die komprimierten Daten geschrieben. In diesem Fall wird deshalb ein FileOutputStream übergeben, der mit einer Datei, deren Namen sich aus dem Namen der Orignaldatei und der Endung gz zusammensetzt, verbunden ist:
  GZIPOutputStream out =
    new GZIPOutputStream(
      new FileOutputStream(args[i]+".gz"));
Im nächsten Schritt werden alle Daten aus dem FileInputStream blockweise ausgelesen und sofort in den GZIPOutputStream geschrieben:
  while((read = in.read(data, 0, 1024)) != -1)
    out.write(data, 0, read);
Durch den Schreibvorgang in den GZIPOutputStream wird automatisch die Komprimierung durchgeführt. Der Lese- und Schreibevorgang erfolgt in diesem Fall Byte-weise, da man sowohl binäre als auch Textdaten verarbeiten kann. Eine Verwendung von Character-Streams ist in diesem Fall deshalb nicht angebracht.

Wurden alle Daten aus der Eingabedatei gelesen, werden sowohl Eingabe-Stream als auch Ausgabe-Stream geschlossen und die Originaldatei gelöscht:
  in.close();
  out.close();
  f.delete();   // Original-Datei löschen

Material zum Beispiel

gunzip

Die Reimplementierung des gunzip-Kommandos ist auch nicht viel umfangreicher. Der Ablauf verläuft analog zur gzip-Reimplementierung. Das Programm erhält per Kommandozeile beliebig viele Namen von Dateien übergeben, deren Inhalt im GZIP-Format komprimiert ist. Da eine Originaldatei in diesem Fall im GZIP-Format vorliegt, erfolgt der Einlesevorgang mit einem GZIPInputStream, der mit der Originaldatei verbunden ist:
 	File f = new File(args[i]);
 	GZIPInputStream in =
 	  new GZIPInputStream(new FileInputStream(f));
Anschließend wird ein FileOutputStream erzeugt, der mit einer Datei verbunden ist, deren Namen aus dem Namen der Originaldatei ohne die Endung gz besteht. Danach werden alle Daten aus dem GZIPInputStream gelesen und in den FileOutputStream geschrieben. Daraufhin werden die beiden Streams geschlossen und die Originaldatei gelöscht.

Material zum Beispiel


 Inhaltsverzeichnis   Auf Ebene Zurück   Seite Zurück   Seite Vor   Auf Ebene Vor   Eine Ebene höher   Index

Copyright © 2002 dpunkt.Verlag, Heidelberg. Alle Rechte vorbehalten.