From 33613a85afc4b1481367fbe92a17ee59c240250b Mon Sep 17 00:00:00 2001
From: Sven Eisenhauer
+Basis der Eingabe-Streams ist die abstrakte Klasse InputStream.
+Sie stellt folgende Methoden zur Verfügung:
+
+
+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.
+
+
+
+
+
+Aus InputStream
+sind einige weitere Klassen direkt abgeleitet. Wie bei den Character-Streams
+bestimmen sie im wesentlichen die Art bzw. die Quelle der Dateneingabe.
+
+
+
+
+
+Ein FileInputStream
+stellt einen Byte-Stream zum Lesen aus einer Datei zur Verfügung.
+Er besitzt einige zusätzliche Konstruktoren:
+
+
+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).
+
+
+
+
+
+
+ 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
+
+
+
+
+
+
+
+
+
+
+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
+19.3.2 Aus InputStream direkt abgeleitete Klassen
+
+FileInputStream
+
+
+
+
+
+
+
+
+
+
+public FileInputStream(String name)
+ throws FileNotFoundException
+
+public FileInputStream(File file)
+ throws FileNotFoundException
+
+public FileInputStream(FileDescriptor fdObj)
+
+
+
+java.io.FileInputStream
+
+
+
+Listing 19.4: Kopieren einer Datei
+
+
+
+
+
+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
+
+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. |
+
+
|
+![]() |
+
+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. + + + + +
+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 | +
+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. + + + + +
+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. + + + + +
+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 | +
+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 | +
+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 | +
+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 | +
+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 | +
+
![]() |
+![]() |
+
+
+ +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. |
+
+
|
+![]() |
+
| 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 + |