Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Vorwort
1 Java ist auch eine Sprache
2 Sprachbeschreibung
3 Klassen und Objekte
4 Der Umgang mit Zeichenketten
5 Mathematisches
6 Eigene Klassen schreiben
7 Angewandte Objektorientierung
8 Exceptions
9 Generics, innere Klassen
10 Die Klassenbibliothek
11 Threads und nebenläufige Programmierung
12 Datenstrukturen und Algorithmen
13 Raum und Zeit
14 Dateien und Datenströme
15 Die eXtensible Markup Language (XML)
16 Grafische Oberflächen mit Swing
17 Grafikprogrammierung
18 Netzwerkprogrammierung
19 Verteilte Programmierung mit RMI und Web–Services
20 JavaServer Pages und Servlets
21 Applets
22 Midlets und die Java ME
23 Datenbankmanagement mit JDBC
24 Reflection und Annotationen
25 Logging und Monitoring
26 Sicherheitskonzepte
27 Java Native Interface (JNI)
28 Dienstprogramme für die Java-Umgebung
Stichwort

Download:
- ZIP, ca. 14,1 MB
Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Java ist auch eine Insel (8. Auflage) von Christian Ullenboom
Programmieren mit der Java Standard Edition Version 6
Buch: Java ist auch eine Insel (8. Auflage)

Java ist auch eine Insel (8. Aufl.)
8., aktual. Auflage, geb., mit DVD
1.475 S., 49,90 Euro
Galileo Computing
ISBN 978-3-8362-1371-4
Pfeil 14 Dateien und Datenströme
Pfeil 14.1 Datei und Verzeichnis
Pfeil 14.1.1 Dateien und Verzeichnisse mit der Klasse File
Pfeil 14.1.2 Verzeichnis oder Datei? Existiert es?
Pfeil 14.1.3 Verzeichnis- und Dateieigenschaften/-attribute
Pfeil 14.1.4 Wurzelverzeichnis, Laufwerksnamen, Plattenspeicher
Pfeil 14.1.5 Umbenennen und Verzeichnisse anlegen
Pfeil 14.1.6 Verzeichnisse listen und Dateien filtern
Pfeil 14.1.7 Dateien berühren, neue Dateien anlegen, temporäre Dateien
Pfeil 14.1.8 Dateien und Verzeichnisse löschen
Pfeil 14.1.9 Verzeichnisse nach Dateien iterativ durchsuchen
Pfeil 14.1.10 URL- und URI-Objekte aus einem File-Objekt ableiten
Pfeil 14.1.11 Mit Locking Dateien sperren
Pfeil 14.1.12 Sicherheitsprüfung
Pfeil 14.2 Dateien mit wahlfreiem Zugriff
Pfeil 14.2.1 Ein RandomAccessFile zum Lesen und Schreiben öffnen
Pfeil 14.2.2 Aus dem RandomAccessFile lesen
Pfeil 14.2.3 Schreiben mit RandomAccessFile
Pfeil 14.2.4 Die Länge des RandomAccessFile
Pfeil 14.2.5 Hin und her in der Datei
Pfeil 14.3 Stream-Klassen und Reader/Writer am Beispiel von Dateien
Pfeil 14.3.1 Mit dem FileWriter Texte in Dateien schreiben
Pfeil 14.3.2 Zeichen mit der Klasse FileReader lesen
Pfeil 14.3.3 Kopieren mit FileOutputStream und FileInputStream
Pfeil 14.3.4 Das FileDescriptor-Objekt
Pfeil 14.4 Basisklassen für die Ein-/Ausgabe
Pfeil 14.4.1 Die abstrakten Basisklassen
Pfeil 14.4.2 Übersicht über Ein-/Ausgabeklassen
Pfeil 14.4.3 Die abstrakte Basisklasse OutputStream
Pfeil 14.4.4 Die Schnittstellen Closeable und Flushable
Pfeil 14.4.5 Ein Datenschlucker
Pfeil 14.4.6 Die abstrakte Basisklasse InputStream
Pfeil 14.4.7 Ressourcen aus dem Klassenpfad und aus Jar–Archiven laden
Pfeil 14.4.8 Ströme mit SequenceInputStream zusammensetzen
Pfeil 14.4.9 Die abstrakte Basisklasse Writer
Pfeil 14.4.10 Die Schnittstelle Appendable
Pfeil 14.4.11 Die abstrakte Basisklasse Reader
Pfeil 14.5 Formatierte Textausgaben
Pfeil 14.5.1 Die Klassen PrintWriter und PrintStream
Pfeil 14.5.2 System.out, System.err und System.in
Pfeil 14.5.3 Geschützte Passwort-Eingaben mit der Klasse Console
Pfeil 14.6 Schreiben und Lesen aus Strings und Byte-Feldern
Pfeil 14.6.1 Mit dem StringWriter ein String-Objekt füllen
Pfeil 14.6.2 CharArrayWriter
Pfeil 14.6.3 StringReader und CharArrayReader
Pfeil 14.6.4 Mit ByteArrayOutputStream in ein Byte-Feld schreiben
Pfeil 14.6.5 Mit ByteArrayInputStream aus einem Byte-Feld lesen
Pfeil 14.7 Datenströme filtern und verketten
Pfeil 14.7.1 Streams als Filter verketten
Pfeil 14.7.2 Gepufferte Ausgaben mit BufferedWriter/BufferedOutputStream
Pfeil 14.7.3 Gepufferte Eingaben mit BufferedReader/BufferedInputStream
Pfeil 14.7.4 LineNumberReader zählt automatisch Zeilen mit
Pfeil 14.7.5 Daten mit der Klasse PushbackReader zurücklegen
Pfeil 14.7.6 DataOutputStream/DataInputStream
Pfeil 14.7.7 Basisklassen für Filter
Pfeil 14.7.8 Die Basisklasse FilterWriter
Pfeil 14.7.9 Ein LowerCaseWriter
Pfeil 14.7.10 Eingaben mit der Klasse FilterReader filtern
Pfeil 14.8 Vermittler zwischen Byte-Streams und Unicode-Strömen
Pfeil 14.8.1 Datenkonvertierung durch den OutputStreamWriter
Pfeil 14.8.2 Automatische Konvertierungen mit dem InputStreamReader
Pfeil 14.9 Kommunikation zwischen Threads mit Pipes
Pfeil 14.9.1 PipedOutputStream und PipedInputStream
Pfeil 14.9.2 PipedWriter und PipedReader
Pfeil 14.10 Datenkompression
Pfeil 14.10.1 Java-Unterstützung beim Komprimieren
Pfeil 14.10.2 Datenströme komprimieren
Pfeil 14.10.3 Zip-Archive
Pfeil 14.10.4 Jar-Archive
Pfeil 14.11 Prüfsummen
Pfeil 14.11.1 Die Schnittstelle Checksum
Pfeil 14.11.2 Die Klasse CRC32
Pfeil 14.11.3 Die Adler32-Klasse
Pfeil 14.12 Persistente Objekte und Serialisierung
Pfeil 14.12.1 Objekte mit der Standard-Serialisierung speichern und lesen
Pfeil 14.12.2 Zwei einfache Anwendungen der Serialisierung
Pfeil 14.12.3 Die Schnittstelle Serializable
Pfeil 14.12.4 Nicht serialisierbare Attribute aussparen
Pfeil 14.12.5 Das Abspeichern selbst in die Hand nehmen
Pfeil 14.12.6 Tiefe Objektkopien
Pfeil 14.12.7 Versionenverwaltung und die SUID
Pfeil 14.12.8 Wie die ArrayList serialisiert
Pfeil 14.12.9 Probleme mit der Serialisierung
Pfeil 14.12.10 Serialisieren in XML-Dateien
Pfeil 14.12.11 JavaBeans Persistence
Pfeil 14.12.12 XStream
Pfeil 14.13 Tokenizer
Pfeil 14.13.1 StreamTokenizer
Pfeil 14.13.2 CSV-Dateien verarbeiten
Pfeil 14.14 Zum Weiterlesen


Galileo Computing - Zum Seitenanfang

14.10 Datenkompression Zur nächsten ÜberschriftZur vorigen Überschrift

Damit Daten weniger Platz auf dem Datenträger einnehmen, werden sie komprimiert. Bei Netzwerkverbindungen ist die logische Konsequenz, dass weniger Daten natürlich auch schneller übertragen werden.

Über alle Plattformen hinweg haben sich Standards gebildet. Zwei Kompressionsstandards sollen an dieser Stelle beschrieben werden.

compress/uncompress, GZip/GunZip

Seitdem der LZW-Algorithmus im Juni 1984 im IEEE-Journal beschrieben wurde, gibt es in jedem Unix-System die Dienstprogramme compress und uncompress, die verlustfrei Daten zusammenpacken und wieder auspacken. [Interessanterweise wurde danach der LZW-Algorithmus von der Sperry Company patentiert – dies zeigt eigentlich, wie unsinnig das Patentrecht in den USA ist.] gzip und gunzip [Gibt es sogar für den C=64: http://www.cs.tut.fi/~albert/Dev/gunzip/.] sind freie Unix-Tools von compress/uncompress und unterliegen der GNU Public License. Das Format enthält eine zyklische Überprüfung bezüglich defekter Daten. Die Endung einer Datei, die mit gzip gepackt ist, ist mit .gz angegeben, wobei die Endung unter compress nur .Z ist. gzip behält die Rechte und Zeitattribute der Dateien bei.

Zip

Das Dienstprogramm zip bündelt in einem Archiv mehrere Dateien und kann die hierarchische Struktur der Ordner erhalten. Auf jede Datei im Zip-Archiv lässt sich anschließend individuell zugreifen. Programme wie WinZip oder 7-Zip können unter Windows Zip-Dateien verarbeiten.

Obwohl Zip und GZip von der Anwendung her unterschiedlich arbeiten – GZip stellt einen Filter dar, der einen Datenstrom komprimiert –, verwenden sie denselben Algorithmus. Beide basieren auf Algorithmen, die im RFC 1952 definiert sind.

Es gibt auch unkomprimierte Zip-Archive (allerdings selten). Ein Beispiel dafür sind die Java-Archive des Internet Explorers. Die größte Datei ist unkomprimiert 5,3 MB groß, gepackt wäre sie 2 MB schwer. Sie wurden aus Gründen der Geschwindigkeit nicht gepackt, da sich die Daten aus unkomprimierten Archiven schneller lesen lassen, weil keine Prozessorleistung für das Entpacken aufzuwenden ist.

Das Archivformat und Archivierungsprogramm tar

Das unter Unix-Systemen bekannte Dienstprogramm tar [»tar« steht für tape archiver, was übersetzt Bandarchivierer heißt.] bündelt mehrere Dateien zu einer neuen Datei, ohne sie zu komprimieren. Das Ergebnis, ein Tar-Archiv, wird oft anschließend mit dem Tool gzip beziehungsweise bzip2 gepackt. Die Endung ist dann .tar.Z. Werden mehrere Daten erst in einem Tar-Archiv zusammengefasst und dann gepackt, ist die Kompressionsrate höher, als wenn jede Datei einzeln komprimiert wird. Der Grund ist simpel: Das Kompressionsprogramm kann die Redundanz besser ausnutzen. Der Nachteil ist freilich, dass für eine Datei gleich das ganze Tar-Archiv ausgepackt werden muss.


Galileo Computing - Zum Seitenanfang

14.10.1 Java-Unterstützung beim Komprimieren Zur nächsten ÜberschriftZur vorigen Überschrift

Unter Java ist ein Paket java.util.zip eingerichtet, um mit komprimierten Dateien zu operieren. Das Paket bietet zur Komprimierung zwei allgemein gebräuchliche Formate: GZip/GunZip zum Komprimieren beziehungsweise Entkomprimieren von Datenströmen und Zip zum Behandeln von Archiven und zum Komprimieren von Dateien. Auch wird das eigene Archiv-Format Jar (Java Archive) durch das Paket java.util.jar unterstützt. Jar ist eine Erweiterung des Zip-Formats. Speziell Klassendateien in Java-Archiven können durch java.util.jar.Pack200 noch höher komprimiert werden.

Tar-Archive werden nicht unterstützt, doch gibt es eine Reihe freier Implementierungen, unter anderem von der Apache Software Foundation: http://tutego.com/go/tarcvs; sie definieren Ein- und Ausgabeströme. Für BZip2 bietet die Apache Foundation Unterstützung über das Paket Commons Compress (http://tutego.com/go/bzip2). Neben der Unterstützung durch das Paket java.util.zip für GZip-Ströme und Zip-Dateien ist TrueZIP (https://truezip.dev.java.net/) eine sehr interessante Open-Source-Bibliothek, die die Behandlung von Archiven stark vereinfacht.


Galileo Computing - Zum Seitenanfang

14.10.2 Datenströme komprimieren Zur nächsten ÜberschriftZur vorigen Überschrift

Zum Packen und Entpacken von Strömen wird GZip verwendet. Wir sehen uns im Folgenden die Datenströme java.util.zip.GZIPInputStream (ein spezieller FilterInputStream) und java.util.zip.GZIPOutputStream (ein FilterOutputStream) genauer an.

Daten packen

Das Paket java.util.zip bietet zwei Unterklassen von FilterOutputStream, die das Schreiben komprimierter Daten ermöglichen: GZIPOutputStream und ZipOutputStream. Um Daten unter dem GZip-Algorithmus zu packen, müssen wir einfach einen vorhandenen Datenstrom zu einem GZIPOutputStream erweitern. Die Klasse ZipOutputStream dient Zip-Archiven, denen wir uns später widmen werden.

OutputStream fos    = new FileOutputStream( file ); 
OutputStream zipout = new GZIPOutputStream( fos );

class java.util.zip.GZIPOutputStream 
extends DeflaterOutputStream

  • GZIPOutputStream( OutputStream out)
    Erzeugt einen packenden Datenstrom mit der voreingestellten Puffergröße von 512 Byte.
  • GZIPOutputStream( OutputStream out, int size )
    Erzeugt einen packenden Datenstrom mit einem Puffer der Größe size.

GZip-Kommandozeilenprogramm

Das folgende Programm soll eine Datei nach dem GZip-Format packen. Es verhält sich in der Arbeitsweise ähnlich wie das unter Unix bekannte Programm gzip.

Listing 14.32 com/tutego/insel/io/zip/gzip.java

package com.tutego.insel.io.zip; 
 
import java.io.*; 
import java.util.zip.*; 
 
public class gzip 
{ 
  public static void main( String[] args ) 
  { 
    if ( args.length != 1 ) { 
      System.err.println( "Benutzung: gzip <source>" ); 
      return; 
    } 
 
    OutputStream os = null; 
    InputStream  is = null; 
 
    try 
    { 
      os = new GZIPOutputStream( new FileOutputStream( args[0] + ".gz" ) ); 
      is = new FileInputStream( args[0] ); 
 
      byte[] buffer = new byte[ 8192 ]; 
 
      for ( int length; (length = is.read(buffer)) != –1; ) 
        os.write( buffer, 0, length ); 
    } 
    catch ( IOException e ) 
    { 
      System.err.println( "Fehler: Kann nicht packen " + args[0] ); 
    } 
    finally 
    { 
      if ( is != null ) try { is.close(); } catch ( IOException e ) { } 
      if ( os != null ) try { os.close(); } catch ( IOException e ) { } 
    } 
  } 
}

Das Programm prüft zuerst, ob ein Argument auf der Kommandozeile vorhanden ist. Aus diesem Argument konstruiert es einen Dateinamen mit der Endung .gz. Der Dateiname bekommt der Konstruktor von FileOutputStream. Den OutputStream dekoriert anschließend der GZIPOutputStream. Die read()-Methode vom FileInputStream liest Block für Block aus der Datei und schreibt die gelesenen Segmente in den GZIPOutputStream, der die Daten komprimiert.

Daten entpacken

Um die Daten zu entpacken, müssen wir nur den umgekehrten Weg beschreiten. Zum Einsatz kommt hier eine der beiden Unterklassen von FilterInputStream. Wieder wickeln wir um einen InputStream einen GZIPInputStream und lesen dann daraus.


class java.util.zip.GZIPInputStream 
extends InflaterInputStream

  • GZIPInputStream( InputStream in, int size )
    Erzeugt einen auspackenden Datenstrom mit einem Puffer der Größe size.
  • GZIPInputStream( InputStream in )
    Erzeugt einen auspackenden Datenstrom mit der voreingestellten Puffergröße von 512 Byte.

GunZip-Kommandozeilenprogramm

Zum Java-Programm gzip wollen wir eine zweite Anwendung hinzunehmen, die sich so verhält wie das unter Unix bekannte Kommandozeilenprogramm gunzip.

Listing 14.33 com/tutego/insel/io/zip/gunzip.java

package com.tutego.insel.io.zip; 
 
import java.io.*; 
import java.util.zip.*; 
 
public class gunzip 
{ 
  public static void main( String[] args ) 
  { 
    if ( args.length != 1 ) { 
      System.err.println( "Benutzung: gunzip <source>" ); 
      return; 
    } 
 
    String source, destination; 
 
    if ( args[0].toLowerCase().endsWith(".gz") ) { 
      source       = args[0]; 
      destination  = source.substring( 0, source.length() – 3 ); 
    } 
    else { 
      source       = args[0] + ".gz"; 
      destination  = args[0]; 
    } 
 
    InputStream  is = null; 
    OutputStream os = null; 
 
    try 
    { 
      is = new GZIPInputStream( new FileInputStream(source) ); 
      os  = new FileOutputStream( destination ); 
 
      byte[] buffer = new byte[ 8192 ]; 
 
      for ( int length; (length = is.read(buffer)) != –1; ) 
        os.write( buffer, 0, length ); 
    } 
    catch ( IOException e ) 
    { 
      System.err.println( "Fehler: Kann nicht entpacken " + args[0] ); 
    } 
    finally 
    { 
      if ( os != null ) try { os.close(); } catch ( IOException e ) { } 
      if ( is != null ) try { is.close(); } catch ( IOException e ) { } 
    } 
  } 
}

Endet die Datei mit .gz, so entwickeln wir daraus den herkömmlichen Dateinamen. Endet sie nicht mit diesem Suffix, so nehmen wir einfach an, dass die gepackte Datei diese Endung besitzt, der Benutzer dies aber nicht angegeben hat. Nach dem Zusammensetzen des Dateinamens holen wir von der gepackten Datei einen FileInputStream und packen einen GZIPInputStream darum. Nun öffnen wir die Ausgabedatei und schreiben in Blöcken zu 8 KB die Datei vom GZIPInputStream in die Ausgabedatei.


Galileo Computing - Zum Seitenanfang

14.10.3 Zip-Archive Zur nächsten ÜberschriftZur vorigen Überschrift

Der Zugriff auf die Daten eines Zip-Archivs unterscheidet sich schon deshalb vom Zugriff auf die Daten eines GZip-Streams, weil diese in Form eines Archivs vorliegen. Unter Zip wird jede eingebettete Datei einzeln und unabhängig komprimiert. Wurden etwa über Tar vorher alle Dateien in ein unkomprimiertes Archiv übernommen, kann der Packalgorithmus GZip beim Packen dieser Dateisammlung bessere Ergebnisse erzielen, als wenn – wie beim Zip-Verfahren – alle Dateien einzeln gepackt würden.

Die Klassen ZipFile und ZipEntry

Objekte der Klasse ZipFile repräsentieren ein Zip-Archiv. Die Einträge im Zip-Archiv sind Dateien und Ordner, die Java durch die Klasse ZipEntry darstellt. Liegt einmal ein ZipEntry-Objekt vor, können ihm durch verschiedene Methoden Dateiattribute entlockt werden, beispielsweise die Originalgröße, das Kompressionsverhältnis, das Datum, wann die Datei angelegt wurde, und Weiteres. Auch kann ein Datenstrom erzeugt werden, sodass sich eine komprimierte Datei im Archiv lesen und schreiben lässt.

Um auf die Dateien eines Archivs zuzugreifen, muss zunächst ein ZipFile-Objekt erzeugt werden.


class java.util.zip.ZipFile

  • ZipFile( String name ) throws ZipException, IOException
  • ZipFile( File file ) throws ZipException, IOException Öffnet ein Zip-Archiv zum Lesen über den Dateinamen oder das File-Objekt.
  • ZipFile( File file, int mode ) throws ZipException, IOException Öffnet ein Zip-Archiv mit dem gegebenen File-Objekt. Der Modus ZipFile.OPEN_READ oder ZipFile.OPEN_READ|ZipFile.OPEN_DELETE bestimmt den Zugriff auf das Archiv.

Eine ZipException ist eine Unterklasse von IOException.

Die im Zip-Archiv abgelegten Dateien oder Verzeichnisse, also die ZipEntry-Einträge, können auf zwei Arten ermittelt werden:

  • Die Methode entries() von ZipFile liefert eine Aufzählung von ZipEntry-Einträgen. Genauer gesagt ist der Rückgabetyp Enumeration<? extends ZipEntry>.
  • Ist der Name der komprimierten Datei oder des Ordners bekannt, liefert getEntry(String) sofort ein ZipEntry-Objekt.

Beispiel Iteriere durch die Einträge eines Archivs, und gib die Namen aus.

ZipFile zf = new ZipFile( "foo.zip" ); 
for ( Enumeration<? extends ZipEntry> e = zf.entries(); e.hasMoreElements(); ) 
{ 
  ZipEntry entry = e.nextElement(); 
  System.out.println( entry.getName() ); 
}


class java.util.zip.ZipFile

  • ZipEntry getEntry( String name )
    Liefert eine Datei aus dem Archiv. null, wenn kein Eintrag mit dem Namen existiert.
  • Enumeration<? extends ZipEntry> entries()
    Gibt eine Aufzählung des Zip-Archivs in Form von ZipEntry-Objekten zurück.
  • String getName()
    Liefert den Pfadnamen des Zip-Archivs.
  • int size()
    Gibt die Anzahl der Einträge im Zip-Archiv zurück.
  • void close() throws IOException
    Schließt das Zip-Archiv.

Eine IllegalStateException ist bei getEntry() und entries() die Folge, wenn das Zip-Archiv schon geschlossen wurde.

Das Objekt ZipEntry und die Datei-Attribute

Ein ZipEntry-Objekt repräsentiert eine Datei oder ein Verzeichnis eines Archivs. Diese Datei kann gepackt (dafür ist die Konstante ZipEntry.DEFLATED reserviert) oder auch ungepackt sein (angezeigt durch die Konstante ZipEntry.STORED). Auf dem Objekt können verschiedene Attribute gesetzt und abgefragt werden. Dadurch lassen sich Statistiken über Kompressionsraten und Weiteres ermitteln.

Listing 14.34 com/tutego/insel/io/zip/ZipListDemo.java, main()

ZipFile zipfile = new ZipFile( file ); 
for ( ZipEntry entry : Collections.list( zipfile.entries() ) ) 
  System.out.printf( "%s%-54s   Size: %6d   Packed: %6d   %tc%n", 
                     entry.isDirectory() ? "+" : " ", 
                     entry.getName(), 
                     entry.getSize(), 
                     entry.getCompressedSize(), 
                     entry.getTime() );

Die Ausgabe könnte zum Beispiel sein:

+a/                  Size:      0   Packed:      0   Do Mai 24 10:13:46 CEST 2007 
 a/a.html            Size:  42924   Packed:   6962   Do Mai 24 10:03:20 CEST 2007 
 a/links.xml         Size:  18900   Packed:   1406   Do Mai 24 10:03:20 CEST 2007

class java.util.zip.ZipEntry 
implements Cloneable

  • String getName()
    Liefert den Namen des Eintrags.
  • void setTime( long time ) Ändert die Modifikationszeit des Eintrags.
  • long getTime()
    Liefert die Modifikationszeit des Eintrags oder –1, wenn diese nicht angegeben ist.
  • void setSize( long size )
    Setzt die Größe der unkomprimierten Datei. Wir werden mit einer IllegalArgumentException bestraft, wenn die Größe kleiner 0 oder größer 0xFFFFFFFF ist.
  • long getSize()
    Liefert die Größe der unkomprimierten Datei oder –1, falls diese unbekannt ist.
  • long getCrc()
    Liefert die CRC-32-Checksumme der unkomprimierten Datei oder –1, falls diese unbekannt ist.
  • void setMethod( int method )
    Setzt die Kompressionsmethode entweder auf STORED oder auf DEFLATED.
  • int getMethod()
    Liefert die Kompressionsmethode. Die Rückgabe ist entweder STORED, DEFLATED oder –1, falls unbekannt.
  • void setExtra( byte[] extra )
    Setzt das optionale Zusatzfeld für den Eintrag. Übersteigt die Größe des Zusatzfelds 0xFFFF Byte, dann wird eine IllegalArgumentException ausgelöst.
  • byte[] getExtra()
    Liefert das Extrafeld oder null, falls es nicht belegt ist.
  • void setComment( String comment )
    Setzt einen Kommentar-String, der 0xFFFF Zeichen lang sein darf (sonst wird eine IllegalArgumentException ausgelöst).
  • String getComment()
    Gibt den Kommentar oder null zurück.
  • long getCompressedSize()
    Liefert die Dateigröße nach dem Komprimieren oder –1, falls diese unbekannt ist. Ist der Kompressionstyp ZipEntry.STORED, dann stimmt diese Größe natürlich mit dem Rückgabewert von getSize() überein.
  • boolean isDirectory()
    Liefert true, falls der Eintrag ein Verzeichnis ist. Der Name der Datei endet mit einem Slash (/).

Auch überschreibt ZipEntry die Methoden toString(), hashCode() und clone() aus Object.

Dateien auspacken

Um Dateien auszupacken, bietet die Java-Bibliothek zwei Möglichkeiten. Die erste ist, mittels getInputStream(ZipEntry) ein InputStream-Objekt zu holen und dann auf den Inhalt der Datei zuzugreifen. (Es ist bemerkenswert, dass getInputStream() keine Methode von ZipEntry ist, sondern von ZipFile.) Die andere Variante arbeitet über ZipInputStream, einen Weg, den wir hier nicht weiter beschreiben.


Beispiel Liegt im Archiv moers.zip die gepackte Datei DerAlteSack.png, dann gelangen wir mit folgenden Zeilen an deren entpackten Inhalt:

ZipFile     zipFile = new ZipFile( "moers.zip" ); 
ZipEntry    entry   = zipFile.getEntry( "DerAlteSack.png" ); 
InputStream is      = zipFile.getInputStream( entry );


class java.util.zip.ZipFile

  • InputStream getInputStream( ZipEntry entry ) throws IOException
    Gibt einen Eingabestrom zurück, mit dem auf den Inhalt einer Datei zugegriffen werden kann. Es folgt eine IllegalStateException, wenn das Zip-Archiv schon geschlossen wurde.

Ein Archiv Datei für Datei entpacken

Damit ein Java-Programm das gesamte Zip-Archiv entpackt, lässt sich mit der Aufzählung von entries() durch das Archiv laufen und für jeden Eintrag eine Datei oder ein Verzeichnis erzeugen. Das Speichern soll eine eigene Methode extractEntry(ZipFile, ZipEntry, String) übernehmen, die zunächst erkennt, ob es sich bei der Datei im Zip-Archiv um ein Verzeichnis handelt oder nicht.

  • Liefert das ZipEntry-Objekt bei isDirectory() ein true, dann legen wir nur einen Ordner mittels mkdirs() an und keine Datei.
  • Steht das ZipEntry für eine Datei, kann diese in einem Unterordner stehen, und es müssen ebenfalls die nötigen Ordner angelegt werden. Nachdem für ein Ziel ein FileOutputStream angelegt wurde, lassen sich alle Bytes von ZipFiles getInputStream(ZipEntry) kopieren.

Listing 14.35 com/tutego/insel/io/zip/unzip.java

package com.tutego.insel.io.zip; 
 
import java.util.zip.*; 
import java.io.*; 
import java.util.*; 
 
public class unzip 
{ 
  private static final byte[] buffer = new byte[ 0xFFFF ]; 
 
  public static void main( String[] args ) 
  { 
    if ( args.length != 2 ) 
      System.out.println( "Benutzung: unzip <zipfile> <destination>" ); 
    else 
    { 
      try 
      { 
        ZipFile zipFile = new ZipFile( args[0] ); 
        Enumeration<? extends ZipEntry> zipEntryEnum = zipFile.entries(); 
 
        while ( zipEntryEnum.hasMoreElements() ) 
        { 
          ZipEntry zipEntry = zipEntryEnum.nextElement(); 
          System.out.print( zipEntry.getName() + "." ); 
          extractEntry( zipFile, zipEntry, args[1] ); 
          System.out.println( ".. unpacked" ); 
        } 
      } 
      catch ( FileNotFoundException e ) 
      { 
        System.err.println( "Fehler: ZipFile nicht gefunden!" ); 
      } 
      catch ( IOException e ) 
      { 
        System.err.println( "Fehler: Allgemeiner Ein-/Ausgabefehler!" ); 
      } 
    } 
  } 
 
  private static void extractEntry( ZipFile zf, ZipEntry entry, String destDir ) 
    throws IOException 
  { 
    File file = new File( destDir, entry.getName() ); 
 
    if ( entry.isDirectory() ) 
      file.mkdirs(); 
    else 
    { 
      new File( file.getParent() ).mkdirs(); 
 
      InputStream  is = null; 
      OutputStream os = null; 
 
      try 
      { 
        is = zf.getInputStream( entry ); 
        os = new FileOutputStream( file ); 
 
        for ( int len; (len = is.read(buffer)) != –1; ) 
          os.write( buffer, 0, len ); 
      } 
      finally 
      { 
        if ( os != null ) os.close(); 
        if ( is != null ) is.close(); 
      } 
    } 
  } 
}

Einträge dem Zip-Archiv hinzufügen

Das Hinzufügen von Dateien zu einem Zip-Archiv unterscheidet sich ein wenig vom Lesen der Dateien, da hier die Klasse ZipFile nicht benötigt wird. Im Mittelpunkt steht die Klasse ZipOutputStream mit zwei Schritten:

  • Ein ZipOutputStream wird aufgebaut, etwa über new ZipOutputStream(new FileOutputStream(zipfile).
  • new ZipEntry(String) oder new ZipEntry(ZipEntry) erzeugt einen Archiv-Eintrag, und putNextEntry(ZipEntry) verbindet dies mit dem ZipOutputStream. Nach dem Schreiben schließt closeEntry() das Hinzufügen ab.

Erzeugt ZipOutputStream eine Datei, lässt sich die Kompressionsrate über die Methode setLevel(int) einstellen. Der Level ist eine Zahl zwischen 0 und 9. Die Kompression übernimmt ein Deflater-Objekt, das im DeflaterOutputStream (die Oberklasse von ZipOutputStream) verwaltet wird. So ruft ZipOutputStream lediglich vom Deflater die Methode setLevel() auf.


Galileo Computing - Zum Seitenanfang

14.10.4 Jar-Archive topZur vorigen Überschrift

Jar-Archive sind mit Zip-Archiven vergleichbar, nur mit dem Unterschied, dass sie eine Manifest-Datei beinhalten. Die Arbeitsweise und der Zugriff auf die Einträge sind daher denen der Zip-Dateien sehr ähnlich. Die Klasse java.util.jar.JarFile repräsentiert ein Jar-Archiv, und ein java.util.jar.JarEntry ist ein Eintrag in dem Archiv. JarFile ist eine Unterklasse von ZipFile und JarEntry eine Unterklasse von ZipEntry.



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.






<< zurück
  Zum Katalog
Zum Katalog: Java ist auch eine Insel





Java ist auch eine Insel
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Tipp
Zum Katalog: Coding for Fun





 Coding for Fun


 Buchempfehlungen
Zum Katalog: Objektorientierte Programmierung





 Objektorientierte
 Programmierung


Zum Katalog: Einstieg in Eclipse 3.4






 Einstieg in
 Eclipse 3.4


Zum Katalog: Java 6 lernen mit Eclipse






 Java 6 lernen
 mit Eclipse


Zum Katalog: NetBeans Platform 6






 NetBeans
 Platform 6


Zum Katalog: Java und XML






 Java und XML


Zum Katalog: Visual C# 2008






 Visual C# 2008


Zum Katalog: IT-Handbuch für Fachinformatiker






 IT-Handbuch für
 Fachinformatiker


Zum Katalog: C++ von A bis Z






 C++ von A bis Z


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Galileo Press 2009
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de