From 33613a85afc4b1481367fbe92a17ee59c240250b Mon Sep 17 00:00:00 2001 From: Sven Eisenhauer Date: Fri, 10 Nov 2023 15:11:48 +0100 Subject: add new repo --- .../hjp5/html/k100128.html | 760 +++++++++++++++++++++ 1 file changed, 760 insertions(+) create mode 100644 Master/Reference Architectures and Patterns/hjp5/html/k100128.html (limited to 'Master/Reference Architectures and Patterns/hjp5/html/k100128.html') diff --git a/Master/Reference Architectures and Patterns/hjp5/html/k100128.html b/Master/Reference Architectures and Patterns/hjp5/html/k100128.html new file mode 100644 index 0000000..f93b84a --- /dev/null +++ b/Master/Reference Architectures and Patterns/hjp5/html/k100128.html @@ -0,0 +1,760 @@ + + + +Handbuch der Java-Programmierung, 5. Auflage + + + + + + + + + +
 Titel  + Inhalt  + Suchen  + Index  + DOC  +Handbuch der Java-Programmierung, 5. Auflage +
 <<  +  <   +  >   + >>  + API  +Kapitel 19 - Byte-Streams +
+
+ + + + +

19.3 Eingabe-Streams

+
+ +
+ + + + +

19.3.1 Die Basisklasse InputStream

+ +

+Basis der Eingabe-Streams ist die abstrakte Klasse InputStream. +Sie stellt folgende Methoden zur Verfügung: +

+ + + + + +
+ +
+public abstract int read()
+  throws IOException
+
+public int read(byte[] b)
+  throws IOException
+
+public int read(byte[] b, int off, int len)
+  throws IOException
+
+public long skip(long n)
+  throws IOException
+
+public int available()
+  throws IOException
+
+public void close()
+  throws IOException
+
+public void mark(int readlimit)
+
+public void reset()
+  throws IOException
+
+public boolean markSupported()
+
+
+
+java.io.InputStream
+ +

+Die read-Methoden +dienen dazu, Bytes zu lesen. Sie können entweder einzelne Bytes +lesen (die als int +zurückgegeben werden, dessen obere 3 Byte leer sind) oder ihre +Daten direkt in einen Bytearray-Puffer schreiben. Mit skip +kann eine beliebige Anzahl Bytes übersprungen werden. available +liefert die Anzahl an Bytes, die ohne Blockieren mindestens gelesen +werden können (Vorsicht, manche Implementierungen geben hier +nie einen Wert größer als 1 zurück). Mit close +wird der Eingabe-Stream geschlossen. + +

+Die Methode markSupported +gibt Auskunft darüber, ob Markieren/Positionieren unterstützt +wird. Ist das der Fall, kann mit mark +die aktuelle Position im Eingabestrom markiert und später mit +reset +dorthin zurückgesprungen werden. Das Argument von mark +gibt dabei die maximale Anzahl an Zeichen an, die der Eingabestrom +sich merken soll. + + + + +

19.3.2 Aus InputStream direkt abgeleitete Klassen

+ +

+Aus InputStream +sind einige weitere Klassen direkt abgeleitet. Wie bei den Character-Streams +bestimmen sie im wesentlichen die Art bzw. die Quelle der Dateneingabe. + + + + +

FileInputStream

+ +

+Ein FileInputStream +stellt einen Byte-Stream zum Lesen aus einer Datei zur Verfügung. +Er besitzt einige zusätzliche Konstruktoren: +

+ + + + + +
+ +
+public FileInputStream(String name)
+  throws FileNotFoundException
+
+public FileInputStream(File file)
+  throws FileNotFoundException
+
+public FileInputStream(FileDescriptor fdObj)
+
+
+
+java.io.FileInputStream
+ +

+Um eine Datei zu öffnen, kann entweder ihr Name oder ein dafür +konstruiertes File-Objekt +verwendet werden (siehe Kapitel 21. +Existiert die Datei nicht oder kann nicht darauf zugegriffen werden, +löst der Konstruktor eine FileNotFoundException +aus. Mit Hilfe des dritten Konstruktors kann ein InputStream +zu einer bereits geöffneten Datei erstellt werden. + +

+Das folgende Programm zeigt die Verwendung der Klassen FileInputStream +und FileOutputStream +zum Kopieren einer Datei (Vorsicht, eine bereits +vorhandene Zieldatei wird ohne Rückfrage überschrieben). + + +

+ + + + + +
+ +
+001 /* FileCopy.java */
+002 
+003 import java.io.*;
+004 
+005 public class FileCopy
+006 {
+007   public static void main(String[] args)
+008   {
+009     if (args.length != 2) {
+010       System.out.println("java FileCopy inputfile outputfile");
+011       System.exit(1);
+012     }
+013     try {
+014       FileInputStream in = new FileInputStream(args[0]);
+015       FileOutputStream out = new FileOutputStream(args[1]);
+016       byte[] buf = new byte[4096];
+017       int len;
+018       while ((len = in.read(buf)) > 0) {
+019         out.write(buf, 0, len);
+020       }
+021       out.close();
+022       in.close();
+023     } catch (IOException e) {
+024       System.err.println(e.toString());
+025     }
+026   }
+027 }
+
+
+FileCopy.java
+ +Listing 19.4: Kopieren einer Datei

+ + + + +

ByteArrayInputStream

+ +

+Die Klasse ByteArrayInputStream +stellt einen Adapter dar, mit dessen Hilfe die Daten aus einem Byte-Array +gelesen werden können. Sie besitzt zwei zusätzliche Konstruktoren, +in denen die Datenquelle angegeben wird: +

+ + + + + +
+ +
+public ByteArrayInputStream(byte[] buf)
+public ByteArrayInputStream(byte[] buf, int offset, int length)
+
+
+
+java.io.ByteArrayInputStream
+

+ + + + + + + + + +
+ +

+Im JDK gibt es eine Klasse StringBufferInputStream, +die einen String als Datenquelle für einen Eingabe-Stream verwendet. +Sie ist seit dem JDK 1.1 deprecated, +weil die Konvertierung von UNICODE-Zeichen in Bytes nicht vollständig +korrekt implementiert wurde. An ihrer Stelle ist die Klasse StringReader +zu verwenden; sie wird in Abschnitt 18.3.2 +erklärt.

+ + + + +
 Hinweis 
+
+ + + + +

ObjectInputStream

+ +

+Ein ObjectInputStream +erlaubt es, primitive Datentypen und Objekte von einem Input-Stream +zu lesen. Zwar ist er nicht von FilterInputStream +abgeleitet, wird aber ebenso verwendet und erwartet im Konstruktor +einen InputStream +als Datenquelle. Die Klasse ObjectInputStream +ist eine der Säulen des Serialisierungs-APIs in Java und wird +in Abschnitt 41.1.3 ausführlich +beschrieben. + + + + +

SequenceInputStream

+ +

+Ein SequenceInputStream +dient dazu, zwei oder mehr Eingabe-Streams so miteinander zu verbinden, +dass die Daten nacheinander aus den einzelnen Streams gelesen werden. +Die beteiligten Streams können entweder in einer Enumeration +oder - wenn es sich um genau zwei von ihnen handelt - direkt an den +Konstruktor übergeben werden: +

+ + + + + +
+ +
+public SequenceInputStream(Enumeration e)
+public SequenceInputStream(InputStream s1, InputStream s2)
+
+
+
+java.io.SequenceInputStream
+ + + + +

PipedInputStream

+ +

+Ein PipedInputStream +ist das Gegenstück zum PipedOutputStream. +Beide zusammen bilden eine Pipe zur Kommunikation zweier Threads. +Ein Beispiel zur Anwendung der beiden Klassen findet sich in Abschnitt 22.4.4. + + + + +

19.3.3 Aus FilterInputStream abgeleitete Klassen

+ +

+FilterInputStream + +

+Die aus InputStream +abgeleitete Klasse FilterInputStream +ist die Basisklasse aller gefilterten Eingabe-Streams. Diese definieren +kein eigenes Eingabegerät, sondern bekommen es beim Instanzieren +in Form eines InputStream-Arguments +übergeben: +

+ + + + + +
+ +
+public FilterInputStream(inputStream in)
+
+
+
+java.io.FilterInputStream
+ +

+Die Aufgabe der aus FilterInputStream +abgeleiteten Klassen besteht darin, die Lesezugriffe abzufangen, in +einer für sie charakteristischen Weise zu verarbeiten und die +Daten erst dann an den Aufrufer weiterzugeben. + + + + +

BufferedInputStream

+ +

+Ein BufferedInputStream +dient zur Pufferung der Eingabedaten. Er kann insbesondere dann die +Performance der Lesezugriffe erhöhen, wenn häufig nur kleine +Datenmengen oder einzelne Bytes gelesen werden müssen. Ein BufferedInputStream +besitzt zwei zusätzliche Konstruktoren, mit denen die Datenquelle +und Puffergröße angegeben werden kann: +

+ + + + + +
+ +
+public BufferedInputStream(InputStream in)
+public BufferedInputStream(InputStream in, int size)
+
+
+
+java.io.BufferedInputStream
+ + + + +

PushbackInputStream

+ +

+Die Klasse PushbackInputStream +erweitert den Eingabe-Stream um die Fähigkeit, bereits gelesene +Zeichen wieder zurückzunehmen. Dazu besitzt sie drei Methoden +mit dem Namen unread, +mit denen einzelne Bytes oder Byte-Arrays wieder zurückgegeben +werden können: +

+ + + + + +
+ +
+public void unread(int b)
+  throws IOException
+
+public void unread(byte[] b, int off, int len)
+  throws IOException
+
+public void unread(byte[] b)
+  throws IOException
+
+
+
+java.io.PushbackInputStream
+ + + + +

DataInputStream und DataInput

+ +

+Analog zum DataOutputStream +gibt es eine Klasse DataInputStream, +mit der die von diesem geschriebenen Daten eingelesen werden können. +Der DataInputStream +implementiert das Interface DataInput, +das folgende Methoden definiert: +

+ + + + + +
+ +
+void readFully(byte[] b)
+  throws IOException
+void readFully(byte[] b, int off, int len)
+  throws IOException
+int skipBytes(int n)
+  throws IOException
+boolean readBoolean()
+  throws IOException
+byte readByte()
+  throws IOException
+int readUnsignedByte()
+  throws IOException
+short readShort()
+  throws IOException
+int readUnsignedShort()
+  throws IOException
+char readChar()
+  throws IOException
+int readInt()
+  throws IOException
+long readLong()
+  throws IOException
+float readFloat()
+  throws IOException
+double readDouble()
+  throws IOException
+String readLine()
+  throws IOException
+String readUTF()
+  throws IOException
+
+
+
+java.io.DataInput
+ +

+Die einzelnen Methoden lesen jeweils ein Element des angegebenen Typs, +das in dem durch die korrespondierende write...-Methode +vorgegebenen binären Format vorliegen muss. readFully +kann dazu verwendet werden, beliebig viele Datenbytes ungeachtet ihres +Datentyps einzulesen. readLine +liest eine Zeile Text aus der Eingabedatei und gibt sie als String +an den Aufrufer zurück. Da die Eingabe byteweise gelesen wird, +werden lediglich UNICODE-Zeichen von \u0000 bis \u00FF korrekt konvertiert. +Die readUnsigned...-Methoden + betrachten die Eingabe als vorzeichenlosen +Wert im Bereich von 0 bis 255 (bzw. 0 bis 65535) und geben niemals +negative Werte zurück. + +

+Das folgende Programm liest die in Listing 19.2 +erzeugten Daten ein und gibt sie auf der Console aus: + + +

+ + + + + +
+ +
+001 /* Listing1905.java */
+002 
+003 import java.io.*;
+004 
+005 public class Listing1905
+006 {
+007   public static void main(String[] args)
+008   {
+009     try {
+010       DataInputStream in = new DataInputStream(
+011                            new BufferedInputStream(
+012                            new FileInputStream("test.txt")));
+013       System.out.println(in.readInt());
+014       System.out.println(in.readInt());
+015       System.out.println(in.readDouble());
+016       System.out.println(in.readUTF());
+017       System.out.println(in.readUTF());
+018       in.close();
+019     } catch (IOException e) {
+020       System.err.println(e.toString());
+021     }
+022   }
+023 }
+
+
+Listing1905.java
+ +Listing 19.5: Verwendung der Klasse DataInputStream

+ + + + +

CheckedInputStream

+ +

+Die Klasse CheckedInputStream +aus dem Paket java.util.zip +dient dazu, die Prüfsumme zu einer Menge von Eingabedaten direkt +beim Einlesen zu berechnen. Sie stellt einen Konstruktor zur Verfügung, +mit dem das gewünschte Prüfsummenverfahren angegeben werden +kann, und besitzt eine Methode getChecksum, +mit der die Prüfsumme ermittelt werden kann: +

+ + + + + +
+ +
+public CheckedInputStream(InputStream in, Checksum cksum)
+
+public Checksum getChecksum()
+
+
+
+java.util.zip.CheckedInputStream
+ +

+Das im Konstruktor erforderliche Objekt muss das Interface Checksum +implementieren. Mit den beiden Klassen CRC32 +und Adler32 +stehen im JDK zwei vordefinierte Implementierungen zur Verfügung. +Das folgende Programm berechnet die Adler-32-Prüfsumme zu der +in der Kommandozeile angegebenen Datei: + + +

+ + + + + +
+ +
+001 /* Listing1906.java */
+002 
+003 import java.io.*;
+004 import java.util.zip.*;
+005 
+006 public class Listing1906
+007 {
+008   public static void main(String[] args)
+009   {
+010     if (args.length != 1) {
+011       System.out.println("Usage: java Listing1906 file");
+012       System.exit(1);
+013     }
+014     try {
+015       CheckedInputStream in = new CheckedInputStream(
+016         new FileInputStream(args[0]),
+017         new Adler32()
+018       );
+019       byte[] buf = new byte[4096];
+020       int len;
+021       while ((len = in.read(buf)) > 0) {
+022         //nichts
+023       }
+024       System.out.println(in.getChecksum().getValue());
+025       in.close();
+026     } catch (IOException e) {
+027       System.err.println(e.toString());
+028     }
+029   }
+030 }
+
+
+Listing1906.java
+ +Listing 19.6: Berechnung der Adler-32-Prüfsumme

+ + + + +

Entpacken von Dateien

+ +

+Analog zur Klasse DeflaterOutputStream +gibt es im Paket java.util.zip +eine Klasse InflaterInputStream +zum Entpacken von gepackten und/oder komprimierten Dateien. Die daraus +abgeleiteten Klassen GZIPInputStream +und ZipInputStream +können direkt zum Entpacken von GZIP- und ZIP-Dateien verwendet +werden. + +

+Das folgende Programm zeigt, wie die mit dem Programm Zip.java +aus Listing 19.3 gepackten Dateien +wieder entpackt und dekomprimiert werden können: + + +

+ + + + + +
+ +
+001 /* Unzip.java */
+002 
+003 import java.io.*;
+004 import java.util.zip.*;
+005 
+006 public class Unzip
+007 {
+008   public static void main(String[] args)
+009   {
+010     if (args.length != 1) {
+011       System.out.println("Usage: java Unzip zipfile");
+012       System.exit(1);
+013     }
+014     try {
+015       byte[] buf = new byte[4096];
+016       ZipInputStream in = new ZipInputStream(
+017                           new FileInputStream(args[0]));
+018       while (true) {
+019         //Nächsten Eintrag lesen
+020         ZipEntry entry = in.getNextEntry();
+021         if (entry == null) {
+022           break;
+023         }
+024         //Beschreibung ausgeben
+025         System.out.println(
+026           entry.getName() +
+027           " (" + entry.getCompressedSize() + "/" +
+028           entry.getSize() + ")"
+029         );
+030         //Ausgabedatei erzeugen
+031         FileOutputStream out = new FileOutputStream(
+032           entry.getName()
+033         );
+034         int len;
+035         while ((len = in.read(buf)) > 0) {
+036           out.write(buf, 0, len);
+037         }
+038         out.close();
+039         //Eintrag schließen
+040         in.closeEntry();
+041       }
+042       in.close();
+043     } catch (IOException e) {
+044       System.err.println(e.toString());
+045     }
+046   }
+047 }
+
+
+Unzip.java
+ +Listing 19.7: Entpacken eines ZIP-Archivs

+

+ + + + + + + + + + + +
+ +

+Das hier vorgestellte Programm dient - wie sein Gegenstück Zip.java +- vor allem als »Proof of Concept«. Einerseits bietet es +nur einen Bruchteil der üblicherweise von einem Entpacker erwarteten +Features (es werden beispielsweise keine Unterverzeichnisse automatisch +erzeugt). Andererseits überschreibt es vorhandene Ausgabedateien +ohne Vorwarnung. Der Umgang mit dem Programm sollte also mit der notwendigen +Umsichtigkeit erfolgen.

+ + + + +
 Warnung 
+
+


+ + + +
 Titel  + Inhalt  + Suchen  + Index  + DOC  +Handbuch der Java-Programmierung, 5. Auflage, Addison +Wesley, Version 5.0.1 +
 <<  +  <   +  >   + >>  + API  +© 1998, 2007 Guido Krüger & Thomas +Stark, http://www.javabuch.de +
+ + + -- cgit v1.2.3