Unterlagen zu Kap. 3 (pdf

Werbung
HOCHSCHULE MUENCHEN
FAKULTÄT FÜR ELEKTROTECHNIK UND INFORMATIONSTECHNIK
FG TECHNISCHE INFORMATIK
V – JV – 300 – 00 – TH – 04
------------------------------------------------------------------------------------
Programmieren in Java
Kapitel 3
3. Elementare Programmfunktionalitäten
3.1.
Zugriff zu Programmparametern
3.2.
Standard-Ein-und-Ausgabe (Konsolen-E/A)
3.3.
Interaktion mit dem Laufzeitsystem
3.4.
Exceptions
3.5.
Dateizugriff
FACHHOCHSCHULE MUENCHEN
FACHBEREICH ELEKTROTECHNIK UND INFORMATIONSTECHNIK
BEREICH DATENTECHNIK
V – JV – 311 – 00 – TH – 01
-----------------------------------------------------------------------------------
Zugriff zu Programmparametern in Java
• Programparameter (Kommandozeilenparameter)
◇ Einem Programm können i.a. beim Aufruf Parameter übergeben werden. Programmparameter
◇ Diese werden beim Aufruf aus der Kommandozeile durch Blanks getrennt an den eigentlichen Programmaufruf
angehängt. Kommandozeilenparameter
Bei Java-Programmen werden sie nach dem Namen der Start-Klasse angegeben.
◇ Beispiel :
java Echo Sie tanzte nur einen Sommer
Kommandozeilenparameter sind :
Sie tanzte nur einen Sommer
• Zugriff im Programm
◇ Die Programmparameter (ohne Namen der Startklasse !) werden in einem String-Array zusammengefasst.
Eine Referenz auf dieses Array wird der main()-Methode der Startklasse als Parameter übergeben.
◇ Die main()-Methode der Startklasse muß daher mit einem Parameter (Argument) vom Typ String[] definiert
werden :
public static void main(String[] args)
{
// ...
}
◇ Innerhalb der main()-Methode stehen damit die Programmparameter als Komponenten des String-Arrays
args zur Verfügung.
◇ Die Anzahl der Programmparameter (= Länge des String-Arrays) ist ermittelbar mittels args.length.
• Beispiel :
// Echo.java
class Echo
{
public static void main(String[] args)
{
for (int i=0; i<args.length; i++)
System.out.println("Parameter "+ i + " : " + args[i]);
}
}
Beispiel eines Programm-Aufrufs :
E:\java\fhm\ee\vorl>java Echo Sie tanzte nur einen Sommer
Parameter
Parameter
Parameter
Parameter
Parameter
0
1
2
3
4
:
:
:
:
:
Sie
tanzte
nur
einen
Sommer
E:\java\fhm\ee\vorl>
FACHHOCHSCHULE MUENCHEN
FAKULTÄT FÜR ELEKTROTECHNIK UND INFORMATIONSTECHNIK
FG TECHNISCHE INFORMATIK
V – JV – 321 – 00 – TH – 04
------------------------------------------------------------------------------------
Standard-Ein- und Ausgabe in Java (1)
• Grundsätzliches zum I/O-Model von Java
◇ Eine Programm-Ein- und Ausgabe findet üblicherweise über Dateien und/oder Geräte statt.
◇ Java betrachtet sowohl Geräte als auch Dateien grundsätzlich als sequentielle Folge von Bytes (Byte-Stream).
Da Java Zeichen und Strings im Unicode darstellt, bietet die Sprache auch die Möglichkeit Textdateien/Text-Geräte
als sequentielle Folge von Unicode-Zeichen (Unicode-Stream) zu interpretieren.
◇ Programmintern wird eine Datei bzw ein Gerät durch ein Objekt einer Stream-Klasse repräsentiert.
◇ Es gibt zahlreiche verschiedene Stream-Klassen, die jeweils unterschiedliche Eigenschaften modellieren.
Alle Stream-Klassen sind im Package java.io enthalten.
◇ Vier abstrakte Klassen sind Basisklassen aller übrigen Stream-Klassen :
▻ InputStream
Basisklasse für Klassen zum byteweisen Lesen (Lesen von Byte-Streams)
▻ Reader
Basisklasse für Klassen zum zeichenweisen Lesen (Lesen von Unicode-Zeichen-Streams)
▻ OutputStream
Basisklasse für Klassen zum byteweisen Schreiben (Schreiben in Byte-Streams)
▻ Writer
Basisklasse für Klasse zum zeichenweisen Schreiben (Schreiben in Unicode-Zeichen-Streams)
Diese Klassen definieren jeweils ein generelles Interface zur Verwendung der Objekte der entsprechenden abgeleiteten
Klassen.
◇ Konverter-Klassen (Brücken-Klassen) erlauben einen Übergang zwischen Byte-Streams und Unicode-ZeichenStreams :
▻ InputStreamReader (abgeleitet von Reader)
Klasse zum zeichenweisen Lesen aus Byte-Streams
▻ OutputStreamWriter (abgeleitet von Writer)
Klasse zum zeichenweisen Schreiben in Byte-Streams
• Standard-Ein- und Ausgabe-Objekte
◇ Für die Standard-Eingabe, die Standard-Ausgabe und die Standard-Fehlerausgabe werden für jedes Programm
automatisch Stream-Objekte angelegt, d.h. die entsprechenden Streams (üblicherweise Tastatur und Bildschirm des
Konsolengeräts) sind implizit geöffnet. Aus historischen Gründen handelt es sich hierbei um Byte-Stream-Objekte.
◇ Referenzen auf diese Stream-Objekte stehen als öffentliche statische Datenkomponenten der – nicht instanzierbaren –
Klasse System (im Package java.lang) zur Verfügung :
▻ public static final InputStream in
Standard-Eingabe-Objekt
▻ public static final PrintStream out
Standard-Ausgabe-Objekt
▻ public static final PrintStream err
Standard-Fehlerausgabe-Objekt
Die Klasse PrintStream ist eine von OutputStream – indirekt – abgeleitete Klasse.
Sie ermöglicht das Schreiben von Werten der einfachen Datentypen und von Objekten beliebiger Klassen (nach
Umwandlung in eine String-Repräsentation) sowie direkt von Strings in einen Byte-Stream.
Hierfür stellt sie die mehrfach überladenen Funktionen print() und println() (nicht explizit formatierbare
Ausgabe) sowie die Methode printf() (formatierte Ausgabe) zur Verfügung.
◇ Ab dem JDK 6.0 kann als Alternative für den Zugriff zum Konsolengerät auch ein vordefiniertes Objekt der Klasse
Console eingesetzt werden.
FACHHOCHSCHULE MUENCHEN
FAKULTÄT FÜR ELEKTROTECHNIK UND INFORMATIONSTECHNIK
FG TECHNISCHE INFORMATIK
V – JV – 322 – 00 – TH – 03
------------------------------------------------------------------------------------
Standard-Ein- und Ausgabe in Java (2)
• Schreiben in die Standard-Ausgabe und Standard-Fehlerausgabe
◇ Mittels der für die Standard-Stream-Objekte
▻ System.out (Standard-Ausgabe, Klasse PrintStream)
▻ System.err (Standard-Fehlerausgabe, Klasse PrintStream)
aufgerufenen Methoden
▻ public void print(...)
▻ public void println(...)
▻ public PrintStream printf(String form, Object... args) (ab dem JDK 5.0)
▻ public PrintStream format(String form, Object... args) (ab dem JDK 5.0)
◇ Die Methoden print() und println() haben jeweils einen Parameter und ermöglichen die Ausgabe
- von boolean-, char-, double-, float-, int- und long-Werten
- von char-Arrays
- von Strings (Objekte der Klasse String)
- sowie der String-Repräsentation (Methode toString()) von Objekten beliebiger Klassen
◇ Die Methode println() ergänzt die Ausgabe um ein Zeilenendezeichen.
Sie lässt sich auch ohne Parameter aufrufen. In diesem Fall bewirkt sie lediglich einen Übergang in eine neue Zeile.
◇ Beispiel :
class StdOutDemo1
{
public static void main(String[] args)
{ boolean b = true;
char
c = 'Z';
int
i = 399127;
long
l = 124L;
float
f = 2.25E-2f;
double d = 0.0/0.0;
String s = "Hallo !";
StdOutDemo1 sod = new StdOutDemo1();
System.out.print(b);
System.out.println();
System.out.println(c);
System.out.println(i);
System.out.println(l);
System.out.println(f);
System.out.println(d);
System.out.println(s);
System.out.println(sod);
}
}
Ausgabe :
true
Z
399127
124
0.0225
NaN
Hallo !
StdOutDemo1@eee36c
◇ Die Anwendung der String-Konkatenation in Verbindung mit der automatischen Umwandlung von beliebigen
Datenwerten und Objekten in eine String-Repräsentation bei ihrem Auftritt in Konkatenations-Aus drücken (Methode
toString()) erlaubt die Ausgabe mehrerer Werte/Objekte mit einem Methodenaufruf.
Achtung : Der +-Operator (Konkatenation, Addition) ist links-rechts-assoziativ.
Damit bei mehrfacher Konkatenation tatsächlich der richtige Gesamtstring entsteht, muss bei der ersten (am weitesten
links stehenden) Verknüpfungsoperation wenigstens ein String beteiligt sein.
Beispiel :
class StdOutDemo2
{
public static void main(String[] args)
{ System.out.println(1 + '+' + 1 + " ergibt " + 2);
System.out.println(1 + "+" + 1 + " ergibt " + 2);
}
}
Ausgabe :
45 ergibt 2
1+1 ergibt 2
FACHHOCHSCHULE MUENCHEN
FAKULTÄT FÜR ELEKTROTECHNIK UND INFORMATIONSTECHNIK
FG TECHNISCHE INFORMATIK
V – JV – 323 – 01 – TH – 04
------------------------------------------------------------------------------------
Standard-Ein- und Ausgabe in Java (3 - 1)
• Formatierte Ausgabe (ab dem JDK 5.0)
◇ Mittels der PrintStream-Methoden
public PrintStream printf(String form, Object... args);
public PrintStream format(String form, Object... args);
Rückgabewert bei beiden Methoden : aktuelles PrintStream-Objekt
◇ Beide Methoden sind in der Wirkung identisch. Sie ermöglichen eine C-ähnliche formatierte Ausgabe
◇ Der erste Parameter form ist der Format-String. Er enthält – analog zum Format-String der C-Funktion
printf() – die einzelnen Formatangaben (format specifier) für die auszugebenden Werte/Objekte.
Durch die Formatangaben wird auch der Typ bzw die Darstellungsart der Ausgabe-Werte festgelegt
Zusätzlich kann der Format-String weiteren Text enthalten, der direkt ausgegeben wird.
◇ Die zweite Parameter-Angabe Object... args bedeutet, dass eine beliebige Anzahl (auch keine) weiterer
Parameter beliebigen Referenz-Typs folgen darf.
Diese Parameter (Argumente) legen die Werte fest, die entsprechend des jeweils spezifizierten Formats auszugeben sind.
Für jede Formatangabe muss ein passendes Argument übergeben werden. Die Typen dieser Argumente müssen zu den
entsprechenden Angaben im Format-String passen. Überflüssige Argumente werden ignoriert
Als Parameter können auch Werte einfacher Datentypen auftreten, da sie mittels Autoboxing automatisch in Objekte der
zugehörigen Wrapper-Klassen umgewandelt werden.
◇ Syntax der Formatangaben (vereinfacht) :
% [flags][width][.precision]conversion
▻ conversion (Konvertierungszeichen)
legt die Formatierungsart und/oder den Typ der Ausgabe fest und schließt eine Formatangabe ab
Die wichtigsten Konvertierungszeichen sind :
b
d
o
x
c
e
f
g
oder B
oder X
oder C
oder E
oder G
s oder S
n
logischer Wert
ganzzahliger Wert in Dezimaldarstellung
ganzzahliger Wert in Oktaldarstellung
ganzzahliger Wert in Sedezimaldarstellung
Unicode-Zeichen
Gleitpunkt-Wert in Exponentialdarstellung
Gleitpunkt-Wert in Dezimalbruchdarstellung
Gleitpunkt-Wert in Dezimalbruchdarstellung oder Exponentialdarstellung
(abhängig von Wert und Genauigkeit)
String (der String, der durch die jeweilige Methode toString() erzeugt wird)
Zeilenendezeichen
Bei einem Großbuchstaben als Konvertierungszeichen werden alle Buchstaben als Großbuchstaben ausgegeben
▻ flags (Steuerflags)
modifizieren das Ausgabeformat, sie können gegebenenfalls miteinander kombiniert werden
Die wichtigsten Steuerflags sind :
+
0
' ' (Blank)
linksbündige Ausgabe
auch positive Werte werden mit Vorzeichen ausgegeben (nur für Zahlen anwendbar)
Ausgabe führender Nullen (nur für Zahlen anwendbar)
Ausgabe positiver Werte mit führendem Blank (nur für Zahlen anwendbar)
▻ width (Ausgabefeldbreite)
legt die minimale Ausgabefeldbreite fest
▻ precision (Genauigkeit)
legt i.a. die maximale Ausgabefeldbreite fest, bei Gleitpunktzahlen jedoch die Anzahl der Nachpunktstellen
(Ausnahme : beim Konvertierungszeichen g bzw G wird die Gesamtzahl der Ziffern festgelegt),
bei Strings : Anzahl der auszugebenden Zeichen des Strings
◇ Nichtzulässige Zeichen in einer Formatangabe sowie fehlende oder zu einer Formatangabe nicht-kompatible Argumente führen zum Werfen einer IllegalFormatException.
FACHHOCHSCHULE MUENCHEN
FAKULTÄT FÜR ELEKTROTECHNIK UND INFORMATIONSTECHNIK
FG TECHNISCHE INFORMATIK
V – JV – 323 – 02 – TH – 02
------------------------------------------------------------------------------------
Standard-Ein- und Ausgabe in Java (3 - 2)
• Ergänzende Anmerkungen zur formatierten Ausgabe (ab dem JDK 5.0)
◇ Es existieren noch weitere Möglichkeiten der Formatierung (insbesondere auch für Datums- und Zeitdarstellungen).
Genauere Informationen können der API-Dokumentation zur Klasse Formatter (Package java.util)
entnommen werden.
◇ Zur Erzeugung von formatierten Ausgaben kann auch die Klasse Formatter eingesetzt werden :
Mit Objekten dieser Klasse ist es u.a. möglich
▻ formatierte Ausgaben direkt in Dateien oder OutputStream- sowie PrintStream-Objekten vorzunehmen
▻ formatierte Strings zu erzeugen (als Objekte der Klassen StringBuffer oder StringBuilder).
Diese Strings können dann explizit ausgegeben (print() oder println()) bzw in Dateien geschrieben
werden.
• Demonstrationsprogramm zur formatierten Ausgabe :
// FormOutpDemo1.java
// Demonstrationsprogramm zur formatierten Ausgabe
public class FormOutpDemo1
{
void show()
{ int anz = 10;
double summe = 99.98765;
float anteil = 0.00005432f;
String type = "Airbus A-380";
System.out.println("0123456789012345678901234567890123456789");
System.out.printf("Anzahl : %5d Summe : %8.3e\n", anz, summe);
System.out.format("Anzahl : %5d Summe : %8.3e\n", anz, summe);
System.out.printf("Anzahl : %-5d Summe : %8.3f\n", anz, summe);
System.out.printf("Anzahl : %0+5d Summe : %08.3f\n", anz, summe);
System.out.printf("Anteil : % .4g\n", anteil);
System.out.printf("Anteil : %.4E\n", anteil);
System.out.printf("Anteil : %.4f\n", anteil);
System.out.printf("Typ : %s\n", type);
System.out.printf("Typ : %15s\n", type);
System.out.printf("Typ : %5s\n", type);
System.out.printf("Typ : %5.6S\n", type);
System.out.printf("Typ : %8.6s\n", type);
System.out.printf("%B\n", true);
}
public static void main(String[] args)
{ FormOutpDemo1 demo = new FormOutpDemo1();
demo.show();
}
Ausgabe des Programms :
0123456789012345678901234567890123456789
Anzahl :
10 Summe : 9.999e+01
Anzahl :
10 Summe : 9.999e+01
Anzahl : 10
Summe :
99,988
Anzahl : +0010 Summe : 0099,988
Anteil : 5.432e-05
Anteil : 5.4320E-05
Anteil : 0,0001
Typ : Airbus A-380
Typ :
Airbus A-380
Typ : Airbus A-380
Typ : AIRBUS
Typ :
Airbus
TRUE
FACHHOCHSCHULE MUENCHEN
FACHBEREICH ELEKTROTECHNIK UND INFORMATIONSTECHNIK
FG TECHNISCHE INFORMATIK
V – JV – 324 – 00 – TH – 04
-----------------------------------------------------------------------------------
Standard-Ein- und Ausgabe in Java (4)
• Lesen aus der Standard-Eingabe
◇ Das für die Standard-Eingabe definierte Stream-Objekt System.in steht als Instanz der Klasse InputStream
zur Verfügung.
Diese Klasse besitzt zum Einlesen lediglich die mehrfach überladene Methode read(), mit der nur einzelne Bytes
oder eine Gruppe von Bytes (Byte-Array) eingelesen werden können.
◇ Üblicherweise soll von der Standard-Eingabe aber Text eingelesen werden, der vom Programm entweder als Wert
eines einfachen Datentyps oder direkt als String interpretiert und verwendet werden soll.
D.h. also, es müssen Zeichenfolgen (Datentyp char) und nicht Bytefolgen (Datentyp Byte) eingelesen werden.
◇ Der über System.in erhältliche Byte-Stream muß also in einen Unicode-Stream umgewandelt werden.
Diese erfolgt mittels eines Objekts der Klasse InputStreamReader.
Dem Konstruktor zur Erzeugung dieses Objekts ist das zugrundeliegende InputStream-Objekt, hier also
System.in als Parameter zu übergeben.
Die Klasse InputStreamReader erlaubt mittels der überladenen Methode read() das Einlesen von Einzelzeichen bzw Zeichen-Arrays.
Einlesen von Einzelzeichen :
public int read() throws IOException
Funktionswert : gelesenes Zeichen bzw –1 bei Eingabeende
◇ Um Strings einlesen zu können, wird ein BufferedReader-Objekt benötigt. Dieses lässt sich unter Verwendung
des InputStreamReader-Objekts, das dem Konstruktor als Parameter zu übergeben ist, erzeugen (Der Konstruktor der Klasse BufferedReader benötigt ein Reader-Objekt als Parameter, die Klasse
InputStreamReader ist von Reader abgeleitet).
Die Klasse BufferedReader stellt neben der überladenen Methode read() zum Einlesen von Einzelzeichen
und Zeichen-Arrays eine Methode zum zeilenweisen Lesen zur Verfügung :
public String readLine() throws IOException
Funktionswert : eingelesene Zeile als String-Objekt (ohne Zeilenende-Zeichen) bzw null wenn das EingabeEnde (EOF, Dateiende) erreicht ist.
Bei der Anwendung dieser Methode (wie auch aller anderen Lese-Methoden) ist zu berücksichtigen, dass bei Auftritt
eines I/O-Fehlers, eine Exception vom Typ IOException geworfen wird.
Diese ist entweder in der aufrufenden Funktion zu fangen oder von dieser weiterzuwerfen.
◇ Darstellung als Klassendiagramm :
BufferedReader
+read():int
+readLine():String
InputStreamReader
+read():int
InputStream
+read():int
◇ Beispiel :
// EchoLines.java
import java.io.*;
class EchoLines
{
public static void main(String[] args) throws IOException
{
BufferedReader stdin = new BufferedReader(
new InputStreamReader(System.in));
String line;
while ((line=stdin.readLine()) != null) System.out.println(line);
}
}
FACHHOCHSCHULE MUENCHEN
FAKULTÄT FÜR ELEKTROTECHNIK UND INFORMATIONSTECHNIK
FG TECHNISCHE INFORMATIK
V – JV – 325 – 00 – TH – 04
------------------------------------------------------------------------------------
Standard-Ein- und Ausgabe in Java (5)
• Lesen aus der Standard-Eingabe, Forts.
◇ Zum Einlesen von Werten der einfachen Datentypen muß der eingelesene String entsprechend dem Datentyp interpretiert und in die interne Wertedarstellung umgewandelt werden.
Hierfür stehen entsprechende statische Methoden der jeweiligen Wrapper-Klassen zur Verfügung :
▻ Klasse Byte
: public static byte parseByte(String str)
throws NumberFormatException;
▻ Klasse Short
: public static short parseShort(String str)
throws NumberFormatException;
▻ Klasse Integer
: public static int
parseInt(String str)
throws NumberFormatException;
▻ Klasse Long
: public static long
parseLong(String str)
throws NumberFormatException;
▻ Klasse Float
: public static float parseFloat(String str)
throws NumberFormatException;
▻ Klasse Double
: public static double parseDouble(String str)
throws NumberFormatException;
Diese Methoden liefern die interne Darstellung des durch den Parameter str repräsentierten Werts des jeweiligen
Typs als Funktionswert zurück. Sie erzeugen eine Exception vom Typ NumberFormatException, wenn str
keinen entsprechenden Zahlenwert darstellt.
◇ Zur Umwandlung eines Strings in einen boolean-Wert müssen zwei Methoden der Wrapper-Klasse Boolean
eingesetzt werden :
▻ Klasse Boolean : public static Boolean valueOf(String str);
Diese Methode erzeugt ein Boolean-Objekt, das den Wert true repräsentiert, wenn der Parameter str
gleich dem String "true" ist , wobei Groß-/Kleinschreibung ignoriert wird ("True" oder "TRUE" z.B.
führen ebenfalls zum Wert true).
Für jeden anderen Wert von str repräsentiert das erzeugte Boolean-Objekt den Wert false.
▻ Klasse Boolean
: public boolean booleanValue();
Diese Methode gibt den durch ein Boolean-Objekt repräsentierten boolean-Wert zurück.
◇ Beispiel :
import java.io.*;
class StdInpDemo
{
public static void main(String[] args) throws IOException
{ int a, b;
BufferedReader stdin = new BufferedReader(
new InputStreamReader(System.in));
System.out.print("Wert von a
? ");
a = Integer.parseInt(stdin.readLine());
System.out.print("Wert von b
? ");
b = Integer.parseInt(stdin.readLine());
System.out.println("a+b = " + (a+b));
System.out.print("Boolean-Wert ? ");
String s = stdin.readLine();
boolean bw = Boolean.valueOf(s).booleanValue();
System.out.println("Eingabe war : " + bw);
}
}
Beispiel für Ein- und
Ausgabe des Programms :
Wert von a
Wert von b
a+b = 634
Boolean-Wert
Eingabe war
? 213
? 421
? True
: true
◇ Eine alternative, flexiblere und einfachere Möglichkeit zum Einlesen von Werten einfacher Datentypen bietet die
mit dem JDK 5.0 eingeführte Klasse Scanner
FACHHOCHSCHULE MUENCHEN
FAKULTÄT FÜR ELEKTROTECHNIK UND INFORMATIONSTECHNIK
FG TECHNISCHE INFORMATIK
V – JV – 326 – 01 – TH – 03
------------------------------------------------------------------------------------
Die Klasse Scanner in Java (1)
• Allgemeines zur Klasse Scanner
◇ Bestandteil des Packages java.util, ab dem JDK 5.0 vorhanden
◇ Objekte der Klasse Scanner dienen zum Zergliedern und Interpretieren von Zeichenfolgen.
◇ Die von Scanner-Objekten bearbeitbaren Zeichenfolgen können aus unterschiedlichen Eingabe-Quellen stammen
(Dateien, sonstige Eingabe-Streams wie z.B. die Standard-Eingabe, Strings).
Die jeweilige Quelle muss beim Erzeugen eines Scanner-Objekts festgelegt werden.
◇ Scanner-Objekte zerlegen ihre Eingabe-Zeichenfolge in Teil-Abschnitte (token). Die Zeichen(-muster), die als
Trennzeichen zwischen den Abschnitten interpretiert werden (delimiter pattern), lassen sich konfigurieren.
Defaultmässig werden Whitespace-Character verwendet.
◇ Die einzelnen Teil-Abschnitte stehen als Strings zur Verfügung und können als Werte eines einfachen Datentyps
interpretiert und in die dem jeweiligen Typ entsprechende interne Darstellung umgewandelt werden.
◇ Damit lassen sich Scanner-Objekte sehr elegant zum Einlesen von Werten der einfachen Datentypen aus der
Standard-Eingabe einsetzen, insbesondere auch dann, wenn in einer Eingabezeile mehrere einzulesende Werte
enthalten sind.
• Konstruktoren der Klasse Scanner (Auswahl)
public Scanner(File source)
Erzeugung eines Scanner-Objekts, dessen Eingabe-Quelle die
durch source spezifizierte Datei ist
public Scanner(Readable source)
Erzeugung eines Scanner-Objekts, dessen Eingabe-Quelle das
durch source spezifizierte Objekt ist. Dieses Objekt muss das
Interface Readable implementieren
public Scanner(InputStream source)
Erzeugung eines Scanner-Objekts, dessen Eingabe-Quelle das
durch source spezifizierte InputStream-Objekt ist
public Scanner(String source)
Erzeugung eines Scanner-Objekts, dessen Eingabe-Quelle der
durch source spezifizierte String ist.
• Memberfunktionen der Klasse Scanner (Auswahl)
public String nextLine()
Rückgabe des Rests der aktuellen Eingabe-Zeile
public boolean hasNextLine()
Überprüfung, ob eine weitere Eingabe-Zeile vorhanden ist, wenn ja true
public String next()
Rückgabe des nächsten Teil-Abschnitts (token) der Eingabe-Zeichenfolge
public boolean hasNext()
Überprüfung ob ein weiterer Teil-Abschnitt vorhanden ist, wenn ja true
public byte nextByte()
public short nextShort()
public int nextInt()
public long nextLong()
public float nextFloat()
public double nextDouble()
public boolean nextBoolean()
Interpretation des nächsten Teil-Abschnitts der Eingabe-Zeichenfolge als
Wert des jeweiligen Typs und Rückgabe der internen Darstellung dieses
Wertes
Jede der Funktionen wirft eine Exception vom Typ
InputMismatchException,
wenn der Teil-Abschnitt sich nicht als Wert des jeweiligen Typs interpretieren
lässt (boolean-Werten können mit Gross- und/oder Kleinbuchstaben dargestellt werden)
FACHHOCHSCHULE MUENCHEN
FAKULTÄT FÜR ELEKTROTECHNIK UND INFORMATIONSTECHNIK
FG TECHNISCHE INFORMATIK
V – JV – 326 – 02 – TH – 01
------------------------------------------------------------------------------------
Die Klasse Scanner in Java (2)
• Demonstrationsbeispiele zur Klasse Scanner
◇ Programm EchoLinesScanDemo
// EchoLinesScanDemo.java
// Echo der von der Standard-Eingabe eingelesenen Zeilen in die Standard-Ausgabe
// Verwendung der Klase Scanner
import java.util.*;
public class EchoLinesScanDemo
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
while (scan.hasNextLine())
System.out.println(scan.nextLine());
}
}
◇ Programm StdInpScanDemo
// StdInpScanDemo.java
// Demonstrationsprogramm zum Einlesen von der Standard-Eingabe
// Verwendung der Klasse Scanner
import java.util.*;
public class StdInpScanDemo
{
public static void main(String[] args)
{
int a, b;
Scanner scan = new Scanner(System.in);
System.out.print("Zwei Integer-Werte a und b ? ");
a = scan.nextInt();
b = scan.nextInt();
System.out.println("a+b = " + (a + b));
System.out.print("Boolean-Wert ? ");
boolean bw = scan.nextBoolean();
System.out.println("Eingabe war : " + bw);
}
}
◇ Beispiel für die Ein- und Ausgabe des Programms StdInpScanDemo
Zwei Integer-Werte a und b ? 12 25
a+b = 37
Boolean-Wert ? FalsE
Eingabe war : false
HOCHSCHULE MUENCHEN
FAKULTÄT FÜR ELEKTROTECHNIK UND INFORMATIONSTECHNIK
FG TECHNISCHE INFORMATIK
V – JV – 327 – 01 – TH – 04
------------------------------------------------------------------------------------
Die Klasse Console in Java (1)
• Allgemeines zur Klasse Console
◇ Bestandteil des Packages java.io, ab dem JDK 6.0 vorhanden
◇ Die Klasse stellt Methoden zum Zugriff zum Konsolengerät zur Verfügung.
Ein Objekt dieser Klasse bildet eine – allerdings nicht immer vorhandene – Alternative zur Verwendung der StandardEin-/Ausgabe-Stream-Objekte.
◇ Die Klasse verfügt über keinen öffentlichen Konstruktor. Sie kann also nicht explizit instanziert werden. Vielmehr
erfolgt eine implizite Instanzierung als Singleton durch die JVM, falls mit dieser ein Konsolengerät verbunden ist.
Dieses ist u.a. immer dann der Fall, wenn die JVM aus einer Kommandozeile heraus ohne Umleitung der Standard-Einund Ausgabe gestartet wird. Das Konsolengerät wird dann typischerweise durch die Tastatur (Standard-Eingabe) und
den Bildschirm (Standard-Ausgabe) gebildet.
Wenn die JVM dagegen aus einem anderen Prozess (z.B. Hintergrundprozess oder IDE) heraus gestartet wird, ist mit ihr
i.a. kein Konsolengerät verbunden.
◇ Das gegebenenfalls vorhandene einzige Objekt der Klasse Console kann mittels der statischen Methode der Klasse
System
public static Console console()
ermittelt werden.
Falls kein Console-Objekt existiert, liefert die Methode null zurück.
◇ Die Klasse Console stellt im wesentlichen die folgenden Funktionalitäten zur Verfügung :
▻ Formatierte Ausgabe
▻ zeilenweises Einlesen
▻ Einlesen von Passwörtern (mit ausgeschalteter Echo-Ausgabe)
▻ Ermittlung der vom Console-Objekt verwendeten Stream-Objekte für die Aus- bzw Eingabe.
Bei diesen Objekten handelt es sich um Zeichen-Stream-Objekte.
Über sie bestehen weitere Möglichkeiten zur Aus- bzw Eingabe.
Anmerkung : Die Standard-Stream-Objekten sind dagegen Byte-Stream-Objekte.
◇ Die Schreib- und Lese-Methoden der Klasse sind synchronisiert, d.h. sie sind für den Einsatz in Multi-Threadanwendungen geeignet.
◇ Die Lese-Methoden geben als Funktionswert null zurück, wenn das Ende des Konsolen-Eingabe-Streams erreicht
ist (Eingabe von Ctrl-Z unter Windows bzw Ctrl-D unter Linux/Unix).
Wenn anschliessend weitere Zeichen eingegeben werden, können sie mit weiteren Lese-Operationen eingelesen weden.
• Memberfunktionen der Klasse Console zur Ermittlung der E/A-Stream-Objekte
◇
public Reader reader()
Ermittlung des mit der Konsole verknüpften Eingabe-Stream-Objekts.
(Objekt der Klasse Reader) Funktionswert
Mittels der von der Klasse Reader implementierten Methoden lassen sich über dieses Eingabe-Stream-Objekt
- Einzelzeichen (Methode read()) sowie
- Zeichenfolgen (mehrere Methoden read(...), s. API-Dokumentation) einlesen
Das Einlesen von Zeichenfolgen über Zeilengrenzen hinweg ist dabei nicht möglich.
Da die Klasse Reader das Interface Readable implementiert, lässt sich das Eingabe-Stream-Obekt als Quelle für
Scanner-Objekte einsetzen.
◇
public PrintWriter writer()
Ermittlung des mit der Konsole verknüpften Ausgabe-Stream-Objekts.
(Objekt der Klasse PrintWriter) Funktionswert
Die Klasse PrintWriter stellt u.a. die gleichen Methoden print(...), println(...), printf(...)
und format(...) zur Verfügung wie die Klasse PrintStream. Damit lassen sich über das Ausgabe-StreamObjekt die gleichen Ausgabe-Operationen wie über die Standard-Ausgabe-Stream-Objekte (System.out und
System.err) realisieren.
FACHHOCHSCHULE MUENCHEN
FAKULTÄT FÜR ELEKTROTECHNIK UND INFORMATIONSTECHNIK
FG TECHNISCHE INFORMATIK
V – JV – 327 – 02 – TH – 02
------------------------------------------------------------------------------------
Die Klasse Console in Java (2)
• Memberfunktionen der Klasse Console zur Ein- und Ausgabe
◇
public Console printf(String form, Object... args)
public Console format(String form, Object... args)
▻ formatierte Ausgabe in den Ausgabe-Stream der Konsole
▻ Beide Methoden besitzen die gleiche Funktionalität
▻ Parameter : form Formatstring, enthält die Formatangaben für die auszugebenden Werte/Objekte
Syntax der Formatangaben s. Methode printf(...) der Klasse PrintStream
args Referenzen auf die auszugebenden Werte/Objekte
▻ Funktionswert : aktuelles Console-Objekt
◇
public void flush()
▻ unmittelbare Ausgabe (Flush) des Buffers des Konsolen-Ausgabe-Streams
◇
public String readLine()
▻ Lesen der nächsten Zeile aus dem Konsolen-Eingabe-Stream
▻ Funktionswert : gelesene Zeile bzw null (wenn am Zeilenende gelesen wird)
Das Zeilenende-Zeichen wird nicht mit zurückgegeben
◇
public String readLine(String form, Object... args)
▻ Ausgabe eines formatierten Prompts in den Konsolen-Ausgabe-Stream,
anschliessend Lesen der nächsten Zeile aus dem Konsolen-Eingabe-Stream
▻ Parameter :
Festlegung des Prompts, s. Parameter der Methode printf(...) (bzw format(...))
▻ Funktionswert : gelesene Zeile bzw null (wenn am Zeilenende gelesen wird)
Das Zeilenende-Zeichen wird nicht mit zurückgegeben
◇
public char[] readPassword()
▻ Lesen eines Passworts aus dem Konsolen-Eingabe-Stream mit ausgeschalteter Echo-Ausgabe
▻ Funktionswert : Gelesenes Passwort (in einem char-Array) bzw null (wenn am Zeilenende gelesen wird)
Ein Zeilenende-Zeichen wird nicht mit zurückgegeben
▻ Anmerkung :
◇
Da die Methode das gelesene Passwort als char-Array und nicht als String-Objekt
zurückgibt, kann es unmittelbar nach Verwendung im Speicher überschrieben werden
public char[] readPassword(String form, Object... args)
▻ Ausgabe eines formatierten Prompts in den Konsolen-Ausgabe-Stream,
anschliessend Lesen eines Passworts aus dem Konsolen-Eingabe-Stream mit ausgeschalteter Echo-Ausgabe
▻ Parameter :
Festlegung des Prompts, s. Parameter der Methode printf(...) (bzw format(...))
▻ Funktionswert : Gelesenes Passwort (in einem char-Array) bzw null (wenn am Zeilenende gelesen wird)
Ein Zeilenende-Zeichen wird nicht mit zurückgegeben
▻ Anmerkung :
Da die Methode das gelesene Passwort als char-Array und nicht als String-Objekt
zurückgibt, kann es unmittelbar nach Verwendung im Speicher überschrieben werden
FACHHOCHSCHULE MUENCHEN
FAKULTÄT FÜR ELEKTROTECHNIK UND INFORMATIONSTECHNIK
FG TECHNISCHE INFORMATIK
V – JV – 327 – 03 – TH – 01
------------------------------------------------------------------------------------
Demonstrationsprogramm zur Klasse Console in Java
• Programm ConsoleDemo
// ConsoleDemo.java
// Demo-Programm zur Klasse Console
import java.io.*;
import java.util.*;
public class ConsoleDemo
{
public static void main(String[] args) throws IOException
{
Console con = System.console();
if (con == null)
{ System.err.println("JVM besitzt keine Console -- Schade");
}
else
{
System.err.println("JVM besitzt eine Console");
con.printf("%s\n", "Das ist gut");
char[] altPass = con.readPassword("%s ", "altes Passwort ?");
con.printf("Die folgende Ausgabe sollte nicht erfolgen :\n");
con.printf("Das Passwort lautet : %s \n", new String(altPass));
con.writer().print("Das Passwort lautet : ");
con.writer().println(altPass);
if (!verifyPasswd(altPass))
con.printf("keine Berechtigung\n");
else
{
char[] neuPass1;
char[] neuPass2;
do
{
neuPass1 = con.readPassword("neues Passwort ? ");
neuPass2 = con.readPassword("neues Passwort wiederholen : ");
}
while (!Arrays.equals(neuPass1, neuPass2));
changePasswd(neuPass1);
Arrays.fill(neuPass1, ' ');
Arrays.fill(neuPass2, ' ');
}
Arrays.fill(altPass, ' ');
}
System.out.print("Geben Sie einen beliebigen String ein : ");
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
String s = stdin.readLine();
System.out.println(s);
}
static void changePasswd(char[] pw)
{
System.out.println("Passwort geaendert !");
}
static boolean verifyPasswd(char[] pw)
{
return true;
}
}
FACHHOCHSCHULE MUENCHEN
FAKULTÄT FÜR ELEKTROTECHNIK UND INFORMATIONSTECHNIK
FG TECHNISCHE INFORMATIK
V – JV – 331 – 00 – TH – 04
------------------------------------------------------------------------------------
Interaktion mit dem Laufzeitsystem in Java (1)
• Die Klasse System
◇ Die Klasse System ist eine nicht-instanzierbare Utility-Klasse (Package java.lang), die einen Zugriff zu
einigen Systemeigenschaften ermöglicht. Im wesentlichen stellt sie zur Verfügung :
▻ die Standard-Ein- und Ausgabe-Objekte (öffentliche statische Datenkomponenten)
▻ eine statische Methode zur Ermittlung des Konsolen-Objekts, falls vorhanden (ab JDK 1.6)
▻ statische Methoden zum Ermitteln (und Ändern) der System-Umgebung ("System Properties")
▻ statische Methoden zum Zugriff zu den aktuellen Environment-Variablen des Betriebssystems (ab JDK 1.5)
▻ statische Methoden zum Setzen und Ermitteln des im System installierten SecurityManager-Objekts
▻ statische Utility-Methoden (z.B. zur Ermittlung der aktuellen Zeit, Teilkopieren von Arrays)
▻ einige statische Methoden, die zum aktuellen Runtime-Objekt zugreifen (Aufruf gleichnamiger Methoden) :
public static void gc()
expliziter Aufruf des Garbage Collectors
public static
void runFinalization()
expliziter Aufruf der finalize()-Methoden aller
zur Vernichtung anstehenden Objekte
public static
void loadLibrary(String libname)
Laden der durch libname spezifizierten dynam.Library
(native Code) Die Zuordnung zwischen Library, Library-Ort,
und Library-Dateiname ist systemabhängig
public static
void load(String filepath)
Laden einer dynam. Library (native Code), die durch den absoluten
Dateipfad filepath referiert wird.
public static void exit(int status)
Beendigung der aktuell laufenden JVM (u. damit des Programms).
Der Parameter status ist der Programm-Exit-Code
Der Aufruf System.method() ist äquivalent zu Runtime.getRuntime().method()
• Ermittlung der aktuellen Zeit
◇ Hierzu dient die statische Methode der Klasse System :
public static long currentTimeMillis();
Rückgabewert : Vergangene Zeit seit dem 1.1.1970 UTC, Mitternacht in Millisekunden
◇ Zur Decodierung dieser Zeit in ihre üblicherweise vom Menschen verwendeten Komponenten (Zeit und Datum)
kann die Bibliotheks-Klasse Date (Package java.util) eingesetzt werden :
▻ Erzeugung eines Date-Objektes, dessen Konstruktor der von currentTimeMillis() zurückgegebene
Wert als Parameter übergeben wird.
▻ Aufruf der Methode public String toString() für dieses Date-Objekt.
Der von dieser Methode als Funktionswert erzeugte String enthält die Zeit (und Datum) in folgender Form :
dow mon dd hh:mm:ss zzz yyyy
◇ Beispiel :
import java.util.Date;
class ActTime
{
public static void main(String[] args)
{ Date act = new Date(System.currentTimeMillis());
System.out.println("aktuelle Zeit : " + act.toString());
}
}
aktuelle Zeit : Wed Aug 08 19:38:30 CEST 2007
FACHHOCHSCHULE MUENCHEN
FACHBEREICH ELEKTROTECHNIK UND INFORMATIONSTECHNIK
FG TECHNISCHE INFORMATIK
V – JV – 332 – 00 – TH – 03
-----------------------------------------------------------------------------------
Interaktion mit dem Laufzeitsystem in Java (2)
• System-Umgebung (System Properties)
◇ Die System-Umgebung besteht aus System-Eigenschaften (System Properties).
Diese werden z. Tl von Standard- Bibliotheks-Klassen benutzt. Sie können aber auch in eigenen Klassen verwendet
werden.
◇ Eine System Property hat einen Namen und einen Wert.
Der Name ist ein String, der durch jeweils einen Punkt in mehrere Abschnitte unterteilt sein kann.
Der Wert ist ebenfalls ein String.
• Änderung der System-Umgebung
◇ Für jede JVM existiert ein Satz von Standard System Properties.
◇ Zusätzlich können benutzerdefinierte System Properties beim Programm- (JVM-) Start festgelegt werden.
Hierzu dient die –D Option beim Aufruf der JVM.
Beispiel :
java –DLabor.aktuell=LSW ActTime
Hierdurch wird die System Property mit dem Namen "Labor.aktuell" und dem Wert "LSW" zusätzlich
gesetzt.
◇ Darüberhinaus können weitere System Properties auch während des Programmlaufs gesetzt werden, vorausgesetzt
das SecurityManager-Objekt erlaubt es.
Zum Setzen (und Ändern) einer System Property existiert in der Klasse System die statische Methode
▻
public static String setProperty(String key, String val)
Die Methode setzt eine System Property mit dem Namen key auf den Wert val.
Als Funktionswert gibt die Methode den zuvor gesetzt gewesenen Wert der System Property bzw – falls diese
noch nicht existiert hat – null zurück.
Beispiel :
System.setProperty("Labor.aktuell", "LSW");
• Ermittlung der System-Umgebung
◇ Properties werden in Objekten der Klasse Properties (Package java.util) gespeichert.
Für die Standard System Properties wird beim Start der JVM ein entsprechendes Objekt angelegt. (SystemProperties-Objekt). Zu ihm kann über die Klasse System zugegriffen werden.
Benutzerdefinierte System Properties (sowohl bei Programmstart festgelegte, als auch im Programm gesetzte) werden
in dieses Objekt eingefügt.
Ein Benutzer kann in einem Programm darüberhinaus weitere Properties-Objekte anlegen.
◇ Statische Methoden der Klasse System zum Zugriff zum System-Properties-Objekt :
▻
public static Properties getProperties()
Funktionswert : das System-Properties-Objekt
▻
public static String getProperty(String key)
Funktionswert : der Wert der System Property mit dem Namen key, bzw null, falls Property nicht existiert
◇ Sämtliche in einem Properties-Objekt enthaltenen Properties (Name/Wert-Paare) lassen sich mittels der
folgenden Methode der Klasse Properties über ein PrintStream-Objekt ausgeben :
public void list(PrintStream out);
FACHHOCHSCHULE MUENCHEN
FAKULTÄT FÜR ELEKTROTECHNIK UND INFORMATIONSTECHNIK
FG TECHNISCHE INFORMATIK
V – JV – 333 – 00 – TH – 03
------------------------------------------------------------------------------------
Interaktion mit dem Laufzeitsystem in Java (3)
• Beispielprogramm zur Ausgabe der System Properties in die Standard-Ausgabe
import java.util.Properties;
class SysProps
{
public static void main(String[] args)
{ System.getProperties().list(System.out);
}
}
-- listing properties -java.runtime.name=Java(TM) SE Runtime Environment
sun.boot.library.path=C:\Programme\Java\jre1.6.0\bin
java.vm.version=1.6.0-b105
java.vm.vendor=Sun Microsystems Inc.
java.vendor.url=http://java.sun.com/
path.separator=;
java.vm.name=Java HotSpot(TM) Client VM
file.encoding.pkg=sun.io
user.country=DE
sun.java.launcher=SUN_STANDARD
sun.os.patch.level=Service Pack 2
java.vm.specification.name=Java Virtual Machine Specification
user.dir=E:\Java\Vorlesung\elemprogfunc
java.runtime.version=1.6.0-b105
java.awt.graphicsenv=sun.awt.Win32GraphicsEnvironment
java.endorsed.dirs=C:\Programme\Java\jre1.6.0\lib\endorsed
os.arch=x86
java.io.tmpdir=C:\DOKUME~1\thomas\LOKALE~1\Temp\
line.separator=
java.vm.specification.vendor=Sun Microsystems Inc.
user.variant=
os.name=Windows XP
sun.jnu.encoding=Cp1252
java.library.path=C:\WINDOWS\system32;.;C:\WINDOWS\Sun\...
java.specification.name=Java Platform API Specification
java.class.version=50.0
sun.management.compiler=HotSpot Client Compiler
os.version=5.1
user.home=C:\Dokumente und Einstellungen\thomas
user.timezone=
java.awt.printerjob=sun.awt.windows.WPrinterJob
file.encoding=Cp1252
java.specification.version=1.6
user.name=thomas
java.class.path=.;C:\Programme\Java\jre1.6.0\lib\ext\...
java.vm.specification.version=1.0
sun.arch.data.model=32
java.home=C:\Programme\Java\jre1.6.0
java.specification.vendor=Sun Microsystems Inc.
user.language=de
awt.toolkit=sun.awt.windows.WToolkit
java.vm.info=mixed mode, sharing
java.version=1.6.0
java.ext.dirs=C:\Programme\Java\jre1.6.0\lib\ext;C:...
sun.boot.class.path=C:\Programme\Java\jre1.6.0\lib\resour...
java.vendor=Sun Microsystems Inc.
file.separator=\
java.vendor.url.bug=http://java.sun.com/cgi-bin/bugreport...
sun.cpu.endian=little
sun.io.unicode.encoding=UnicodeLittle
sun.desktop=windows
sun.cpu.isalist=
FACHHOCHSCHULE MUENCHEN
FACHBEREICH ELEKTROTECHNIK UND INFORMATIONSTECHNIK
FG TECHNISCHE INFORMATIK
V – JV – 334 – 00 – TH – 01
-----------------------------------------------------------------------------------
Interaktion mit dem Laufzeitsystem in Java (4)
• Zugriff zu den Environment-Variablen des Betriebssystems
◇ Ab dem JDK 5.0 kann in Java-Programmen wieder zu den vom Betriebssystem verwalteten Environment-Variablen
zugegriffen werden.
◇ Eine Environment-Variable besitzt – wie eine System Property – einen Namen und hat einen Wert.
Sowohl Name als auch Wert sind jeweils ein String. Jede Environment-Variabale bildet ein String-Paar.
◇ Mit den folgenden statischen Methoden der Klasse System kann zu dem bei der Programmabarbeitung aktuellen
Environment zugegriffen werden :
▻
public static Map<String, String> getenv()
Ermittlung aller aktuellen Environment-Variablen.
Funktionswert : - String-String-Map , die die Environment-Variablen enthält.
Falls das Betriebssystem keine Environment-Variablen unterstützt, ist die zurückgegebene
Map leer.
Eine Map ist ein assoziativer Container, der Schlüssel (key) –Werte (value)-Paare speichert.
Als Schlüssel dient hier der Name einer Environment-Variablen, der Wert ist der Wert dieser Variablen
▻
public static String getenv(String name)
Ermittlung des Werts der Environment-Variablen mit dem Namen name
Funktionswert : - Wert der Environment-Variablen
- bzw null, wenn keine Environment-Variable mit dem Namen name existiert
Falls ein Security Manager installiert ist, wird er von beiden Funktionen befragt, ob der Zugriff zum Environment
zulässig ist.
Bei Unzulässigkeit wird eine SecurityException geworfen.
◇ Beispielprogramm zum Zugriff zu den Environment-Variablen
Auflistung aller Environmentvariablen (Name = Wert) in die Standard-Ausgabe
// GetEnv.java
// Ermittlung des aktuellen Environments
import java.util.*;
public class GetEnv
{
public static void main(String[] args)
{
Map<String, String> env = System.getenv();
Set<String> keys = env.keySet();
for (String name : keys)
System.out.println(name + " = " + System.getenv(name));
}
}
FACHHOCHSCHULE MUENCHEN
FAKULTÄT FÜR ELEKTROTECHNIK UND INFORMATIONSTECHNIK
FG TECHNISCHE INFORMATIK
V – JV – 335 – 00 – TH – 01
------------------------------------------------------------------------------------
Die Klasse Runtime in Java (1)
• Grundsätzliches
◇ Die Klasse Runtime befindet sich im Package java.lang.
◇ Jede Java-Applikation besitzt genau ein Objekt dieser Klasse. Es wird beim Start der JVM automatisch erzeugt.
Dieses Objekt bildet ein Interface zwischen der Java-Applikation und der Laufzeitumgebung der ausführenden JVM.
◇ Zur Ermittlung des aktuellen Runtime-Objekts dient die statischen Methode der Klasse Runtime :
static Runtime getRuntime()
Runtime.getRuntime() liefert das mit der aktuellen Java-Applikation assoziierte Runtime-Objekt.
◇ Eine explizite Instanzierung der Klasse ist nicht möglich.
◇ Die Klasse Runtime stellt Funktionalitäten in folgenden Bereichen zur Verfügung :
▻ Information über Systemresourcem der JVM (Prozessoranzahl, Arbeitsspeicher)
▻ expliziter Aufruf des Garbage Collectors
▻ Ausführung externer Programme in Kindprozessen
▻ Laden dynamischer Bibliotheken (nativer Code)
▻ Debug-Unterstützung
▻ Beendigung (shutdown) der JVM
• Information über Systemresourcen der JVM
◇ Hierfür dienen die folgenden Methoden der Klasse Runtime
public int availableProcessors()
Rückgabe der Anzahl Prozessoren, die der JVM zur Verfügung stehen
public long freeMemory()
Ermittlung des freien der JVM zur Verfügung stehenden Arbeitsspeichers,
Funktionswert = freier Arbeitsspeicher in Bytes
public long totalMemory()
Ermittlung des gesamten der JVM zur Verfügung stehenden Arbeitspeichers, Funktionswert = gesamter Arbeitsspeicher in Bytes
public long maxMemory()
Ermittlung der maximalen Arbeitspeichergröße, die die JVM zu nutzen
versuchen wird (in Bytes)
Falls keine obere Grenze existiert, Rückgabe von Long.MAX_VALUE
◇ Demonstrationsbeispiel :
public class ResInfo
{
public static void main(String[] args)
{ Runtime rt = Runtime.getRuntime();
System.out.println("Einige Systemresourcen der JVM :");
System.out.println("Anzahl
Prozessoren
: " + rt.availableProcessors());
System.out.println("gesamter Arbeitsspeicher : " + rt.totalMemory() + " Bytes");
System.out.println("freier
Arbeitsspeicher : " + rt.freeMemory() + " Bytes");
System.out.println("maximaler Arbeitsspeicher : " + rt.maxMemory() + " Bytes");
}
}
Einige Systemresourcen der JVM :
Anzahl
Prozessoren
: 2
gesamter Arbeitsspeicher : 5177344 Bytes
freier
Arbeitsspeicher : 4997096 Bytes
maximaler Arbeitsspeicher : 66650112 Bytes
FACHHOCHSCHULE MUENCHEN
FAKULTÄT FÜR ELEKTROTECHNIK UND INFORMATIONSTECHNIK
FG TECHNISCHE INFORMATIK
V – JV – 336 – 00 – TH – 02
------------------------------------------------------------------------------------
Die Klasse Runtime in Java (2)
• Ausführung externer Programme in Kindprozessen
◇ Die Erzeugung von Kindprozessen, die ein anzugebendes Programm ausführen, wird durch mehrere überladene
Methoden mit dem Namen exec ermöglicht.
◇ Alle exec-Methoden geben bei Erfolg als Funktionswert ein Objekt der Klasse Process zurück.
Dieses Objekt repräsentiert den neu erzeugten Kindprozeß. Es ermöglicht dem Elternprozeß hinsichtlich bestimmter
Aspekte eine Interaktion mit dem erzeugten Kindprozeß (z.B. Warten auf Kindprozeßende, Ermittlung des ReturnCodes des Kindprozesses, Abbruch des Kindprozesses)
◇ Beim Auftreten von Fehlern werfen die exec-Methoden entsprechende Exceptions.
So werfen alle exec-Methoden beim Auftreten eines I/O-Fehlers (z.B. Programmdatei nicht gefunden) eine
IOException.
◇ Falls ein Security Manager installiert ist (ein SecurityManager-Objekt existiert), überprüft dieser, ob die Ausführung des angegebenen Programms zulässig ist. Bei Unzulässigkeit wird eine SecurityException geworfen.
◇ Überblick über die exec-Methoden (Auswahl) :
public Process exec(String cmd)
throws IOException
Ausführung des durch cmd referierten Programms in einem neu
erzeugten Kindprozeß
public Process exec(String[] cmdarr) Ausführung des durch cmdarr[0] referierten Programms in einem
throws IOException
neu erzeugten Kindprozeß. Die übrigen Elemente von cmdarr
(ab Index 1) werden dem Programm als Programmparameter übergeben
public Process exec(String cmd,
String[] envp)
throws IOException
Ausführung des durch cmd referierten Programms in einem neu
erzeugten Kindprozeß
envp referiert das dem Programm zu übergebende Environment
public Process exec(String[] cmdarr, Ausführung des durch cmdarr[0] referierten Programms in einem
String[] envp)
neu erzeugten Kindprozeß. Die übrigen Elemente von cmdarr
throws IOException
(ab Index 1) werden dem Programm als Programmparameter übergeben
envp referiert das dem Programm zu übergebende Environment
Wird kein Environment angegeben (Methoden mit nur einem Parameter bzw envp == null) so wird dem im
Kindprozess ausgeführten Programm das Environment des Elternprozesses übergeben
Es existieren zwei weitere exec-Methoden (3 Parameter), mit denen für den neu erzeugten Kindprozeß explizit das
Arbeitsdirectory festgelegt werden kann. Wird für den entsprechenden Parameter null übergeben so erbt – wie bei
den o.a. exec-Methoden – der Kindprozeß das Arbeitsdirectory des Elternprozesses.
◇ Einfaches Demonstrationsbeispiel :
import java.io.*;
class ExecDemo
{
public static void main(String[] args) throws IOException
{ String[] cmd = null;
if (args.length>0)
cmd = args;
else
{ cmd = new String[1];
cmd[0]= "calc";
}
Runtime.getRuntime().exec(cmd);
}
}
FACHHOCHSCHULE MUENCHEN
FACHBEREICH ELEKTROTECHNIK UND INFORMATIONSTECHNIK
FG TECHNISCHE INFORMATIK
V – JV – 341 – 00 – TH – 03
-----------------------------------------------------------------------------------
Exceptions in Java (1)
• Prinzip des Exception Handlings
◇ Java stellt – wie auch C++ – einen speziellen Mechanismus zur Behandlung von Ausnahmesituationen (Fehlerfällen,
Exceptions), die während der Programmausführung auftreten können, zur Verfügung ⇒ Exception Handling
◇ Ausnahmesituationen in diesem Sinne sind Fehler, oder sonstige unerwünschte Sonderfälle (z.B. Dateizugriffsfehler,
Verletzung von Array-Grenzen, Datenformatfehler usw), die im normalen Programmablauf nicht auftreten sollten,
aber auftreten können.
Exception Handling ist kein Mechanismus zur Behandlung von externen oder internen Interrupts.
◇ Exception Handling trennt den Code, der Fehler verursachen kann, von dem Code, der einen aufgetretenen Fehler
behandelt.
Dadurch kann der eigentliche den normalen Programmablauf steuernde (produktive) Code frei gehalten werden von
einer ständigen Überprüfung auf den Auftritt von Fehlern und Sonderfällen sowie der Reaktion auf diese. Dies trägt
erheblich zur Klarheit und Übersichtlichkeit des Codes bei.
◇ Code (z.B. eine Methode einer Bibliotheksklasse), der eine Ausnahmesituation entdeckt, wirft eine Exception, die
dann von einem anderen Code-Teil, dem Exception-Handler gefangen wird.
Im Exception-Handler findet die Reaktion auf die (Bearbeitung der) Ausnahmesituation statt. Diese kann der Fehlerart
sowie der jeweiligen spezifischen Programmsituation angepasst werden. Z.B. kann eine Fehlermeldung ausgegeben
werden und anschliessend das Programm fortgesetzt oder beendet werden. Oder es kann versucht werden, die Fehlerursache zu beseitigen und das Programm dann fortzusetzen.
◇ Exceptions werden als Objekte behandelt. Sie enthalten Informationen über die Fehlerursache und stellen Methoden
zum Zugriff zu diesen zur Verfügung.
Werfen einer Exception (throwing) bedeutet das Erzeugen eines Objekts einer Exception-Klasse und die anschliessende Suche eines passenden Exception-Handlers.
Wird ein derartiger Handler gefunden, wird ihm das Exception-Objekt (genauer eine Referenz darauf) übergeben
( Fangen der Exception, catching).
Dem Handler stehen damit die im Exception-Objekt enthaltenen Informationen zur Auswertung zur Verfügung.
◇ Exception Handling wird in Java wesentlich umfangreicher und strikter als in C++ angewendet :
▻ In der Standard-Bibliothek sind zahlreiche Exception-Klassen definiert.
Sie bilden eine über mehrere Pakete verteilte Klassenhierarchie, die die Klasse Throwable (von Object
abgeleitet, Paket java.lang) als Wurzelklasse besitzt.
Im Konstruktor einer derartigen Klasse wird i.a. die Exception-Ursache bzw eine Kurzbeschreibung der Exception
durch einen String (fest codiert oder als Parameter übergeben) festgelegt.
▻ Viele Methoden vieler Bibliotheksklassen werfen Exceptions.
▻ Java erzwingt, dass geworfene Exceptions gefangen werden müssen. Existiert in einem Benutzerprogramm kein
geeigneter Exception-Handler, so werden sie von einem in der JVM angesiedelten Standard-Handler behandelt,
der Informationen über die Exception in die Standard-Ausgabe ausgibt und anschliessend das Programm (genauer
den aktuellen Thread) beendet.
▻ Ein Benutzer kann jederzeit eigene Exception-Klassen definieren. Dies kann sinnvoll sein, wenn spezielle Fehlerfälle gesondert von anderen behandelt werden sollen (z.B. "Division durch Null" als Spezialfall einer
ArithmeticException).
Eine beutzerdefinierte Exception-Klasse muß von einer der Standard-Bibliotheks-Exception-Klassen abgeleitet
sein
FACHHOCHSCHULE MUENCHEN
FACHBEREICH ELEKTROTECHNIK UND INFORMATIONSTECHNIK
BEREICH DATENTECHNIK
V – JV – 342 – 00 – TH – 03
-----------------------------------------------------------------------------------
Exceptions in Java (2)
• Hierarchie der Bibliotheks-Exception-Klassen
◇ Alle Exception-Klassen sind – direkt oder indirekt – von der Klasse Throwable abgeleitet.
◇ Die Klasse Throwable (Paket java.lang) ist eine direkte Unterklasse von Object.
◇ Überblick über den Anfang der Hierarchie :
Throwable
Error
VirtualMachineError
weitere
Error-Klassen
ArithmeticException
Exception
RuntimeException
IOException
weitere
RuntimeExceptionKlassen
FileNotFoundException
weitere
ExceptionKlassen
weitere
IOExceptionKlassen
◇ Exceptions der Klasse Error sowie der davon abgeleiteten Klassen kennzeichnen ernsthafte Systemfehler, die
normalerweise nicht auftreten sollten, aber prinzipiell jederzeit auftreten können.
Ein normales Benutzerprogramm kann auf derartige Exceptions i.a. nicht sinnvoll reagieren und sollte sie deswegen
auch nicht fangen. Vielmehr sollten sie immer vom Default-Exception-Handler der JVM behandelt werden.
◇ Exceptions der Klasse RuntimeException sowie der davon abgeleiteten Klassen können ebenfalls prinzipiell
an beliebiger Stelle während des Programmablaufs auftreten. I.a. liegt ihre Ursache in einem logischen Programmierfehler (z.B. Division durch 0 oder unzulässiger Array-Index). Eine vernünftige Reaktion zur Laufzeit ist i.a. nicht
möglich. Derartige Fehler sollten i.a. im Programm-Code korrigiert werden.
Ein Benutzerprogramm kann diese Exceptions behandeln (d.h. geeignete Exception-Handler bereitstellen), muß es aber
nicht. Im letzteren Fall erfolgt wiederum eine Behandlung durch den Default-Handler der JVM.
◇ Exceptions aller übrigen Klassen (z.B. IOException) repräsentieren Fehler, mit denen man prinzipiell rechnen
muß (z.B. Datei ist nicht vorhanden) und die deswegen auch in irgendeiner Weise behandelt werden müssen.
Für diese Exceptions schreibt Java eine "catch-or-declare"-Erfordernis vor. Sie müssen von der Funktion, in der sie
geworfen werden, entweder gefangen oder von ihr als weiter-werfbar deklariert werden.
Andererseits darf eine Funktion nur solche Exceptions dieser Klassen werfen, die sie auch deklariert hat.
Das Einhalten dieser Erfordernis kann vom Compiler überprüft werden. Sie werden daher als geprüfte (checked)
Exceptions bezeichnet.
◇ Exceptions der Klassen Error und RuntimeException sowie der davon abgeleiteten Klassen sind dagegen
ungeprüfte (unchecked) Exceptions. Sie können jederzeit geworfen werden, ohne daß sie von der entsprechenden
Funktion deklariert werden müssen. Für sie gilt die "catch-or-declare"-Erfordernis nicht, sie dürfen aber deklariert
werden
FACHHOCHSCHULE MUENCHEN
FACHBEREICH ELEKTROTECHNIK UND INFORMATIONSTECHNIK
FG TECHNISCHE INFORMATIK
V – JV – 343 – 00 – TH – 02
-----------------------------------------------------------------------------------
Exceptions in Java (3)
• Die Klasse Throwable
◇ Die direkt von der Klasse Object abgeleitete Klasse Throwable (Paket java.lang) ist Basisklasse aller
Exception-Klassen.
◇ Sie definiert ein allgemeines Interface für den Zugriff zu den Exception-Objekten aller Exception-Klassen
Die vier wichtigsten Methoden dieses Interfaces sind :
▻ public String getMessage();
Diese Methode gibt den bei der Exception-Objekt-Erzeugung gespeicherten Ursachen- bzw KurzbeschreibungsString als Funktionswert zurück, bzw null, falls kein derartiger String gespeichert wurde.
▻ public String toString();
Diese Methode erzeugt einen String, der aus dem vollqualifizierten Namen der tatsächlichen Klasse des ExceptionObjekts besteht, gegebenenfalls (falls getMessage() einen Wert !=null zurückgibt) gefolgt von ": " und
dem Rückgabewert von getMessage().
▻ public void printStackTrace();
Diese Methode gibt den Funktionswert von toString() gefolgt von dem Aufruf-Stack der Funktion, in der
die Exception ursprünglich geworfen wurde, in die Standard-Fehler-Ausgabe (System.err) aus.
▻ public void printStackTrace(PrintStream s);
Diese Methode gibt den Funktionswert von toString() gefolgt von dem Aufruf-Stack der Funktion, in der
die Exception ursprünglich geworfen wurde, in den durch s referierten Print-Stream aus.
• Deklaration werfbarer Exceptions (throws-Klausel)
◇ Die von einer Funktion werfbaren geprüften Exceptions müssen von dieser deklariert werden.
Werfbare ungeprüfte Exceptions können, müssen aber nicht deklariert werden.
◇ Die Deklaration erfolgt durch eine im Funktionskopf nach der Parameterliste anzugebende throws-Klausel.
Die throws-Klausel besteht aus dem Schlüsselwort throws, gefolgt von einer durch Kommata getrennten
Auflistung von Exception-Klassen
◇ Syntax :
throws
Exception-Klasse
,
◇ Beispiel :
public String liesEtwas(String dname)
throws FileNotFoundException, EOFException
{
// ...
}
• Werfen einer Exception
◇ Mittels einer throw-Anweisung.
Nach dem Schlüsselwort throw ist eine Referenz auf das zu werfende Exception-Objekt anzugeben.
Diese Referenz kann
▻ der Wert eines new-Ausdrucks sein (neu erzeugtes Exception-Objekt)
▻ die einem Exception-Handler übergebene Objekt-Referenz sein ("Weiterwerfen" der Exception)
◇ Syntax :
◇ Beispiel :
throw
Exception-Objekt-Referenz
;
throw new ArithmeticException("Nenner ist Null");
FACHHOCHSCHULE MUENCHEN
FAKULTÄT FÜR ELEKTROTECHNIK UND INFORMATIONSTECHNIK
FG TECHNISCHE INFORMATIK
V – JV – 344 – 00 – TH – 02
------------------------------------------------------------------------------------
Exceptions in Java (4)
• Die try-Anweisung
◇ Sie ermöglicht das Fangen von Exceptions.
◇ Eine try-Anweisung besteht i.a. aus drei Teilen :
▻ dem try-Block
▻ einem oder mehreren catch-Blöcken
▻ einem finally-Block
Entweder die catch-Blöcke oder der finally-Block dürfen auch fehlen, aber nicht beides.
◇ Syntax :
try
{
catch
(
finally
Anweisung
Exception-Klasse
}
Name
{
Anweisung
}
{
Anweisung
}
)
◇ Der try-Block enthält den eigentlichen produktiven Code, der auf den Auftritt von Exceptions überwacht wird.
Er wird solange ausgeführt, bis entweder durch eine der Anweisungen eine Exception (direkt durch eine throw-Anweisung oder indirekt durch eine aufgerufene Funktion) geworfen wird oder alle Anweisungen erfolgreich abgearbeitet
worden sind.
Beim Auftritt einer Exception wird der try-Block sofort verlassen und nach einem Exception-Handler gesucht,
der die Exception fangen kann.
◇ Die catch-Blöcke bilden die Exception-Handler.
Jeder catch-Block ist zuständig für das Fangen von Exceptions einer bestimmten Klasse bzw deren Unterklassen.
Die von einem catch-Block fangbare Exception-Klasse ist in seinem Kopf – analog zur Parameter-Deklaration von
Funktionen – angegeben. Da Objekte (genauer Objekt-Referenzen) einer Klasse zuweisungskompatibel zu Variablen
einer Basisklasse sind, können auch Exceptions aller Klassen, die von der deklarierten Klasse abgeleitet sind, gefangen
werden.
Die Suche nach einem "passenden" Exception-Handler erfolgt in der Reihenfolge ihrer Angabe im Quellcode.
Wird ein Exception-Handler gefunden, der die geworfene Exception fangen kann, wird das Programm mit seiner
Abarbeitung fortgesetzt. Dabei wird die Exception wie ein formaler Funktionsparameter an den Handler übergeben.
Wird kein "passender" Exception-Handler gefunden, wird die Suche in der jeweils nächsten umfassenden try-Anweisung (gegebenenfalls in der aufrufenden Funktion) fortgesetzt.
Bleibt auch das erfolglos, wird der Default-Exception-Handler der JVM ausgeführt und das Programm beendet.
◇ Der finally-Block enthält Code, der immer ausgeführt wird, unabhängig davon, wie die try-Anweisung
verlassen wird, ob durch reguläre Beendigung des try-Blocks oder durch Werfen einer gefangenen oder nicht
gefangenen Exception.
Die Ausführung des finally-Blocks erfolgt unmittelbar vor Verlassen des try-Blocks bzw – beim Fangen einer
Exception – vor Verlassen des entsprechenden catch-Blocks. Die Ausführung erfolgt auch dann, wenn try- bzw
catch-Block mit einer return-Anweisung verlassen werden.
Der finally-Block wird insbesondere verwendet, um Aufräumarbeiten durchzuführen und sicherzustellen, dass
belegte System-Resourcen (z.B. geöffnete Dateien) freigegeben werden
FACHHOCHSCHULE MUENCHEN
FACHBEREICH ELEKTROTECHNIK UND INFORMATIONSTECHNIK
BEREICH DATENTECHNIK
V – JV – 345 – 00 – TH – 01
-----------------------------------------------------------------------------------
Exceptions in Java (5)
• Demonstrationsprogramm zu Exceptions
// ExceptDemo.java
import java.io.*;
class ExceptDemo
{
public void func1()
{ try
{ System.out.println("in func1() : Aufruf von func2()");
func2();
System.out.println("normales Ende von try in func1()!");
return;
}
finally
{ System.out.println("func1() verlassen !");
}
}
public void func2()
{ try
{ System.out.println("in func2() : Aufruf von func3()");
func3();
System.out.println("normales Ende von try in func2()!");
return;
}
catch (RuntimeException e)
{ System.out.print("Exception-Handler in func2() : ");
System.out.println(e.getMessage());
}
finally
{ System.out.println("func2() verlassen !");
}
}
public void func3()
{ try
{ System.out.println("in func3() : Exception wird geworfen");
throw new RuntimeException("Demo-Exception !");
}
catch (ArithmeticException e)
{ System.out.print("Exception-Handler in func3() : ");
System.out.println(e.getMessage());
}
finally
{ System.out.println("func3() verlassen !");
}
}
public static void main(String[] args)
{ ExceptDemo ed = new ExceptDemo();
ed.func1();
}
}
in func1() : Aufruf von func2()
in func2() : Aufruf von func3()
in func3() : Exception wird geworfen
func3() verlassen !
Exception-Handler in func2() : Demo-Exception !
func2() verlassen !
normales Ende von try in func1()!
func1() verlassen !
FACHHOCHSCHULE MUENCHEN
FACHBEREICH ELEKTROTECHNIK UND INFORMATIONSTECHNIK
BEREICH DATENTECHNIK
V – JV – 351 – 00 – TH – 01
-----------------------------------------------------------------------------------
Dateizugriff in Java (1)
• Überblick
◇ Java behandelt Dateien als sequentielle Folge von Bytes (Byte-Streams)
◇ In der IO-Bibliothek (Package java.io) sind zahlreiche Klassen definiert, die das Arbeiten mit Dateien unterstützen.
Die wichtigsten dieser Klassen sind :
▻ die File-Stream-Klassen zum sequentiellen Zugriff
• FileInputStream (byteweises Lesen)
• FileOutputStream (byteweises Schreiben)
• FileReader (zeichenweises Lesen)
• FileWriter (zeichenweises Schreiben)
▻ eine Klasse zum wahlfreien Zugriff (Lesen und Schreiben)
• RandomAccessFile
▻ Klassen für den Zugriff zum Dateisystem
• FileDescriptor
• File
◇ Auszugsweises Klassendiagramm :
Anmerkungen :
▻ Das Diagramm beschränkt sich auf die Datei-Eingabe-Stream-Klassen (FileInputStream, FileReader).
▻ Für die Datei-Ausgabe-Stream-Klassen (FileOutputStream, FileWriter) bestehen analoge Ableitungsund Nutzungsbeziehungen.
Deren – direkte oder indirekte – Basisklassen sind OutputStream bzw Writer.
▻ Die IO-Bibliothek enthält eine Reihe weiterer – hier nicht aufgeführter – Streamklassen, die zumeist von
InputStream oder Reader (bzw OutputStream oder Writer) direkt oder indirekt abgeleitet sind.
InputStream
Reader
FilterInputStream
BufferedInputStream
DataInputStream
InputStreamReader
FileInputStream
FileReader
FileDescriptor
File
BufferedReader
RandomAccessFile
FACHHOCHSCHULE MUENCHEN
FAKULTÄT FÜR ELEKTROTECHNIK UND INFORMATIONSTECHNIK
FG TECHNISCHE INFORMATIK
V – JV – 352 – 01 – TH – 04
------------------------------------------------------------------------------------
Dateizugriff in Java (2-1)
• Die Klasse File
◇ Objekte dieser Klasse repräsentieren Zugriffspfade (zu Dateien bzw Directories) im Dateisystem.
◇ Wesentliche Funktionalitäten :
▻ Speicherung eines Datei- bzw Directory-Zugriffspfades in einer abstrakten system-unabhängigen Darstellung,
sowie Bereitstellung von Informationen über denselben
▻ Ermittlung diverser Eigenschaften einer repräsentierten Datei (bzw eines repräsentierten Directories)
▻ Manipulation von Dateisystem-Einträgen (Erzeugen, Löschen, Änderung bestimmter Eigenschaften)
◇ Der repräsentierte Zugriffspfad kann durch einen absoluten oder einen relativen Pfadnamen bezeichnet sein.
Ein relativer Pfadname wird immer auf das aktuelle Arbeitsdirectory des Users bezogen (Wert der System Property
user.dir). Typischerweise handelt es sich hierbei um das Directory, aus dem die JVM gestartet wurde.
◇ Zugriffspfade bestehen aus :
▻ einem optionalen betriebsystem-abhängigen Prefix-String (z.B. "D:\\", "E:" oder "/")
▻ einer Folge von keinem oder mehr Namen-Strings, die jeweils ein Directory bzw (nur der letzte String) eine
Datei bezeichnen. Die einzelnen Namen-Strings sind durch ein betriebssystem-abhängiges Trennzeichen separiert.
Das betriebssystem-abhängige Trennzeichen ist der Wert der System Property file.separator.
Es steht auch als öffentliche statische Datenkomponente der Klasse File zur Verfügung :
public static final char separatorChar; bzw
public static final String separator; (String mit einem Zeichen)
◇ Konstruktoren :
▻ public File(String path)
Erzeugung eines neuen File-Objekts, das den Zugriffspfad path repräsentiert.
Falls path==null ist, wird eine NullPointerException geworfen.
▻ public File(String dirName, String name)
Erzeugung eines neuen File-Objekts, das den aus dirName und name gebildeten Zugriffspfad repräsentiert.
(Eintrag name im Directory dirName).
Äquivalent zu : File(dirName + File.separator + name)
Falls name==null ist, wird eine NullPointerException geworfen.
▻ public File(File fileDir, String name)
Erzeugung eines neuen File-Objekts, das den Zugriffspfad repräsentiert, der aus dem Eintrag name in dem
durch fileDir repräsentierten Directory gebildet wird,
Äquivalent zu : File(fileDir.getPath(), name)
Falls name==null ist, wird eine NullPointerException geworfen.
▻ public File(URI uri)
Erzeugung eines neuen File-Objekts, dessen repräsentierter Zugriffspfad durch Konvertierung des Unified
Resource Identifiers erhalten wird, der durch das URI-Objekt uri repräsentiert wird. Es muß sich hierbei
um den Resource Identifier einer Datei handeln (Beginn mit file:)
Falls uri==null ist, wird eine NullPointerException geworfen.
Falls uri keine Datei repräsentiert, wird eine IllegalArgumentException geworfen.
◇ Der durch ein File-Objekt repräsentierte Zugriffspfad muß nicht einen tatsächlich existierenden Dateisystem-Eintrag
referieren.
Zur Überprüfung, ob ein entsprechender Dateisystem-Eintrag vorhanden ist, d.h. durch das File-Objekt also tatsächlich eine Datei oder ein Directory repräsentiert wird, dient die Memberfunktion
▻ public boolean exists()
Funktionswert : true, wenn der Eintrag existiert,
false, wenn der Eintrag nicht existiert
FACHHOCHSCHULE MUENCHEN
FAKULTÄT FÜR ELEKTROTECHNIK UND INFORMATIONSTECHNIK
FG TECHNISCHE INFORMATIK
V – JV – 352 – 02 – TH – 03
------------------------------------------------------------------------------------
Dateizugriff in Java (2-2)
• Die Klasse File, Forts.
◇ Methoden zum Erzeugen neuer Dateisystem-Einträge
▻ public boolean createNewFile() throws IOException
Diese Methode erzeugt eine neue leere Datei mit dem vom aktuellen File-Objekt repräsentierten Zugriffspfad,
falls noch keine Datei mit diesem Zugriffspfad existiert.
Funktionswert : true, falls die Datei erzeugt werden konnte
false, falls eine Datei mit dem Zugriffspfad bereits existiert hat.
Falls ein I/O-Fehler auftritt, wird eine IOException geworfen.
▻ public boolean mkdir()
Diese Methode erzeugt eine neues Directory mit dem vom aktuellen File-Objekt repräsentierten Zugriffspfad
Funktionswert : true, falls das Directory erzeugt werden konnte, andernfalls false
▻ public boolean mkdirs()
Diese Methode erzeugt ein neues Directory mit dem vom aktuellen File-Objekt repräsentierten Zugriffspfad
sowie gegebenenfalls alle noch nicht existierenden Eltern-Directories.
Funktionswert : true, falls das Directory und alle noch nicht existierenden Eltern-Directories erzeugt
werden konnten
false, falls das Directory nicht erzeugt werden konnte.
Anm. : In diesem Fall können durchaus einige Eltern-Directories erzeugt worden sein.
◇ Methoden zur Ermittlung von Informationen über Dateisystem-Einträge
▻ public String getAbsolutePath()
Rückgabe des absoluten Pfadnamens
▻ public String getCanonicalPath() Rückgabe des kanonischen Pfadnamens
▻ public long length()
Rückgabe der Dateilänge, bei Directories undefinierter Funktionswert
▻ public boolean isDirectory() true, wenn Eintrag existiert und Directory ist, sonst false
▻ public boolean isFile()
true, wenn Eintrag existiert und normale Datei ist, sonst false
▻ public boolean isHidden()
true, wenn Eintrag existiert und verborgen ist, sonst false
▻ public boolean canWrite()
true, wenn Eintrag existiert und geändert werden kann, sonst false
▻ public boolean canRead()
true, wenn Eintrag existiert und gelesen werden kann, sonst false
▻ public String[] list()
Wenn Eintrag ein Directory ist : Rückgabe einer Auflistung aller in ihm
enthaltenen Einträge als String-Array (ausser "." und "..")
Wenn Eintrag kein Directory ist : Rückgabe von null
▻ public File[] listFiles()
Wie list(), nur Rückgabe der Einträge als File-Array
◇ Methoden zur Veränderung von Dateisystem-Einträgen
▻ public boolean renameTo(File newPath)
Umbenennen / Verschieben des aktuell repräsentierten Dateisystem-Eintrags.
Der Dateisystem-Eintrag wird anschliessend durch das File-Objekt newPath repräsentiert.
Der vom aktuellen Objekt bisher repräsentierte Eintrag existiert anschliessend nicht mehr.
Funktionswert : true, falls Umbenennen / Verschieben erfolgreich war, andernfalls false
Falls newPath==null ist, wird eine NullPointerException geworfen.
▻ public boolean delete()
Löschen des aktuell repräsentierten Dateisystem-Eintrags. Ein zu löschendes Directory muss es leer sein.
Funktionswert : true, falls erfolgreich gelöscht werden konnte, andernfalls false
◇ Es existieren noch zahlreiche weiterer Methoden.
◇ Alle Methoden, die zu einer System Property zugreifen oder einen Zugriff zum Dateisystem bewirken, werfen eine
SecurityException, wenn der Zugriff nicht zulässig ist.
FACHHOCHSCHULE MUENCHEN
FACHBEREICH ELEKTROTECHNIK UND INFORMATIONSTECHNIK
BEREICH DATENTECHNIK
V – JV – 352 – 03 – TH – 01
-----------------------------------------------------------------------------------
Dateizugriff in Java (2-3)
• Demoprogramm 1 zur Klasse File
// TestRename.java
import java.io.*;
public class TestRename
{
public static void main(String[] args) throws IOException
{
if (args.length<=1)
System.out.println("Angabe von Quell- und Zielpfad erforderlich");
else
{
File fil = new File(args[0]);
if (!fil.exists())
{ System.out.print("Quellpfad \"" + args[0] + "\" existiert nicht");
if (fil.createNewFile())
System.out.println(" --> neu erzeugt");
else
System.out.println(" --> Erzeugung nicht möglich");
}
if (fil.exists())
{
System.out.println("Dateigroesse : " + fil.length() + " Bytes");
File neufil = new File(args[1]);
boolean succ = fil.renameTo(neufil);
if (!succ)
System.out.println("rename nicht erfolgreich");
else
{
System.out.println("rename erfolgreich");
System.out.print("alter Pfad : " + fil);
if (!fil.exists())
System.out.println(" existiert nicht mehr");
System.out.println("neuer Pfad : " + neufil);
}
}
}
}
Beispiele für Programmaufruf und -ausgabe
E:\Java\fhm\ee\vorl\fileacc>java TestRename ftest2.txt ftest2.dat
Dateigroesse : 33 Bytes
rename erfolgreich
alter Pfad : ftest2.txt existiert nicht mehr
neuer Pfad : ftest2.dat
E:\Java\fhm\ee\vorl\fileacc>java TestRename ftest2.txt ftest2.dat
Quellpfad "ftest2.txt" existiert nicht --> neu erzeugt
Dateigroesse : 0 Bytes
rename nicht erfolgreich
FACHHOCHSCHULE MUENCHEN
FAKULTÄT FÜR ELEKTROTECHNIK UND INFORMATIONSTECHNIK
FG TECHNISCHE INFORMATIK
V – JV – 352 – 04 – TH – 03
------------------------------------------------------------------------------------
Dateizugriff in Java (2-4)
• Demoprogramm 2 zur Klasse File
// ListDir.java
import java.io.*;
public class ListDir
{
public static void main(String[] args)
{
try
{ if (args.length<=0)
throw new IOException("Programmparameter (Directory-Pfad) fehlt !");
File dir = new File(args[0]);
if (!dir.exists())
throw new IOException("\"" + args[0] + "\" existiert nicht !");
if (!dir.isDirectory())
throw new IOException("\"" + dir.getAbsolutePath() + "\" ist kein Directory!");
String[] entries = dir.list();
System.out.println("Inhalt des Directories \"" + dir.getAbsolutePath() + "\" :");
for (int i=0; i<entries.length; i++)
System.out.println(entries[i]);
}
catch (IOException ex)
{
System.out.println(ex.getMessage());
}
}
}
Beispiele für Programmaufruf und -ausgabe
E:\Java\fhm\ee\vorl\fileacc>java ListDir
Programmparameter (Directory-Pfad) fehlt !
E:\Java\fhm\ee\vorl\fileacc>java ListDir meindir
"meindir" existiert nicht !
E:\Java\fhm\ee\vorl\fileacc>java ListDir ftestdir
"E:\Java\fhm\ee\vorl\fileacc\ftestdir" ist kein Directory!
E:\Java\fhm\ee\vorl\fileacc>java ListDir .
Inhalt des Directories "E:\Java\fhm\ee\vorl\fileacc\." :
FileTest1.java
FileTest1.class
ftest.txt
ftest2.dat
TestRename.java
TestRename.class
ftest1.dat
ftest3.txt
testren1.txt
testren2.txt
ftestdir
ListDir.java
ListDir.class
FACHHOCHSCHULE MUENCHEN
FAKULTÄT FÜR ELEKTROTECHNIK UND INFORMATIONSTECHNIK
FG TECHNISCHE INFORMATIK
V – JV – 353 – 00 – TH – 04
------------------------------------------------------------------------------------
Dateizugriff in Java (3)
• Die Klasse FileDescriptor
◇ Objekte dieser Klasse bilden ein Handle zu der vom jeweiligen Betriebssystem für eine geöffnete Datei (allgemeiner :
für einen geöffneten Stream) angelegten Verwaltungsstruktur.
◇ Jedes Objekt, über dem ein Zugriff zu einer Datei erfolgt (Objekt einer File-Stream-Klasse bzw der Klasse
RandomAccessFile) ist mit einem FileDescriptor-Objekt assoziiert. Dieses stellt die Verbindung zur
Dateiverwaltung auf der Betriebssystemebene her.
◇ Ein FileDescriptor-Objekt wird üblicherweise implizit beim Anlegen eines Objekts für den Dateizugriff und
dem damit verbundenen Öffnen der Datei erzeugt.
Ein explizites Erzeugen eines FileDescriptor-Objekts ist weder üblich noch sinnvoll.
Mit dem zur Verfügung stehenden öffentlichen parameterlosen Konstruktor kann nur ein ungültiges Objekt, das an keine
geöffnete Datei gebunden ist, erzeugt werden.
◇ Für Objekte der Klassen FileInputStream, FileOutputStream und RandomAccessFile (nicht jedoch
der Klassen FileReader und FileWriter) kann mit der jeweiligen Methode getFD() das mit ihnen
assoziierte FileDescriptor-Objekt ermittelt werden.
◇ Bei der Erzeugung eines neuen File-Stream-Objekts kann auch ein existierendes FileDescriptor-Objekt
verwendet werden. Das neue File-Stream-Objekt referiert dann dieselbe Datei wie das File-Stream-Objekt, das das
FileDescriptor-Objekt geliefert hat. Damit kann über zwei (oder mehr) Stream-Objekte zur selben Datei zugegriffen werden.
◇ Methoden der Klasse FileDescriptor
▻
public boolean valid()
Überprüfung, ob das FileDescriptor-Objekt gültig, d.h. an eine geöffnete Datei gebunden ist.
Funktionswert : true, falls das Objekt an eine geöffnete Datei gebunden ist, andernfalls false
▻
public void sync() throws SyncFailedException
Synchronisation aller System-Buffer, die Daten für die referierte Datei enthalten, mit dem physikalischen
Speichermedium.
Die Funktion kehrt erst dann zurück, wenn alle relevanten Daten auf das physikalische Medium geschrieben
worden sind.
Die Methode sorgt nicht für das Herausschreiben von Buffern, die in dem Anwendungsprogramm verwendet
werden (z.B. von einem BufferedOutputStream-Objekt). Diese müssen gegebenenfalls zuvor an das
Betriebssystem übergeben werden (mittels der jeweiligen Stream-Methode flush()).
Wenn eine Synchronisation der System-Buffer mit dem physikalischen Speichermedium nicht sichergestellt
werden kann, wird eine SyncFailedException geworfen.
◇ Die Klasse FileDscriptor stellt Handle zu den Standard-Streams als öffentliche statische Datenkomponenten zur Verfügung
Normalerweise werden diese jedoch nicht direkt von User-Code verwendet sondern indirekt über die durch die Klasse
System bereitgestellten Standard-Stream-Objekte.
▻ public static final FileDescriptor in
Handle zum Standard-Eingabe-Stream
▻ public static final FileDescriptor out
Handle zum Standard-Ausgabe-Stream
▻ public static final FileDescriptor err
Handle zum Standard-Fehlerausgab-Stream
FACHHOCHSCHULE MUENCHEN
FAKULTÄT FÜR ELEKTROTECHNIK UND INFORMATIONSTECHNIK
FG TECHNISCHE INFORMATIK
V – JV – 354 – 01 – TH – 04
------------------------------------------------------------------------------------
Dateizugriff in Java (4-1)
• Die File-Stream-Klassen
◇ Objekte dieser Klassen ermöglichen einen sequentiellen Zugriff zu Dateien :
▻ FileInputStream (byteweises Lesen)
▻ FileOutputStream (byteweises Schreiben)
▻ FileReader (zeichenweises Lesen)
▻ FileWriter (zeichenweises Schreiben)
◇ Überblick über die Konstruktoren :
1.Parameter
2. Parameter
String path
Dateizugriffspfad
File fil
repräsentiert Dateizugriffspfad
-------
existiert für Klasse
FileInputStream
FileOutputStream
FileReader
FileWriter
FileDescriptor fd
referiert geöffnete Datei
String path
Dateizugriffspfad
File fil
repräsentiert Dateizugriffspfad
Beispiel :
boolean app
wenn true : Anhängen an Datei (append)
wenn false : Schreiben am Dateianfang
FileOutputStream
FileWriter
public FileInputStream(File datei) throws FileNotFoundException
● Bei der Erzeugung eines File-Stream-Objekts für einen Dateizugriffspfad (Param. vom Typ String bzw. File)
▻ wird die referierte Datei – falls sie vorhanden und die jeweilige Zugriffsart zulässig ist – geöffnet
▻ und ein an sie gebundenes FileDescriptor-Objekt erzeugt.
Die Konstruktoren der Datei-Ausgabe-Stream-Klassen versuchen die referierte Datei neu anzulegen, falls sie nicht
existiert.
Kann eine Datei nicht geöffnet werden (z.B. weil der Zugriffspfad ein Directory referiert), wird eine
FileNotFoundException geworfen.
● Bei der Erzeugung eines File-Stream-Objekts für eine bereits geöffnete Datei (Parameter vom Typ
FileDescriptor)
▻ wird zu der Datei – falls die jeweilige Zugriffsart zulässig ist – ein weiterer Zugriffskanal geöffnet
● Alle Konstruktoren werfen eine SecurityException, wenn ein SecurityManager-Objekt existiert und
dieser feststellt, dass die jeweilige Zugriffsart nicht zulässig ist.
◇ Schliessen eines File-Streams
mittels der für alle File-Stream-Klassen existierenden Methode
▻
public void close() throws IOException
Die Methode schliesst den File-Stream und damit die referierte Datei und gibt alle sonstigen mit dem Stream
assoziierten System-Resourcen frei.
Beim Auftritt eines I/O-Fehlers wird eine IOException geworfen.
FACHHOCHSCHULE MUENCHEN
FAKULTÄT FÜR ELEKTROTECHNIK UND INFORMATIONSTECHNIK
FG TECHNISCHE INFORMATIK
V – JV – 354 – 02 – TH – 05
------------------------------------------------------------------------------------
Dateizugriff in Java (4-2)
• Die File-Stream-Klassen, Forts.
◇ Ermittlung des assoziierten FileDescriptor-Objekts
Dies ist nur für die Klassen FileInputStream und FileOutputStream möglich.
Für diese Klassen existiert die Methode
▻
public final FileDescriptor getFD() throws IOException
Die Methode gibt das mit dem Stream-Objekt assoziierte FileDescriptor-Objekt zurück.
Beim Auftritt eines I/O-Fehlers wird eine IOException geworfen.
◇ Methoden zum Dateizugriff
Die File-Stream-Klassen stellen das von ihrer jeweiligen Basisklasse definierte Stream-Zugriffs-Interface zur
Verfügung. Die wichtigsten Methoden dieser Interfaces sind :
Methode
Wirkung
existiert für Klasse
void write(int b)
void write(byte[] buff)
void write(byte[] buff,
int pos, int len)
Schreiben des Bytes b
Schreiben des Byte-Buffers buff
Schreiben von len Bytes aus buff
ab Position pos
FileOutputStream
void write(int c)
void write(char[]
void write(char[]
int pos, int
void write(String
Schreiben des Zeichens c
Schreiben des Zeichen-Buffers buff
Schreiben von len Zeichen aus buff
ab Position pos
Schreiben des Strings str
FileWriter
void flush()
Herausschreiben aller Schreib-Buffer
(Übergabe an das Betriebssystem)
FileOutputStream
FileWriter
int read()
Lesen eines Bytes (= Funktionswert)
Funktionswert == -1 bei Dateiende
Lesen einer Byte-Folge,
Ablage im Buffer buff
Funktionswert : Anzahl gelesener Bytes
bzw –1 bei Dateiende
FileInputStream
buff)
buff,
len)
str)
int read(byte[] buff)
int read()
int read(char[] buff)
long skip(long n)
Lesen eines Zeichens (= Funktionswert)
FileReader
Funktionswert == -1 bei Dateiende
Lesen einer Zeichen-Folge,
Ablage im Buffer buff
Funktionswert : Anzahl gelesener Zeichen
bzw –1 bei Dateiende
Überlesen der nächsten n Bytes
bzw der nächsten n Zeichen
FileInputStream
FileReader
Es existieren noch weitere Methoden, mit denen auch Teile eines Byte- bzw Zeichen-Arrays gelesen bzw Teile
eines Strings geschrieben werden können.
Alle Methoden für den Dateizugriff werfen eine IOException, wenn ein I/O-Fehler auftritt.
alle Methoden sind mit der throws-Klausel throws IOException definiert.
FACHHOCHSCHULE MUENCHEN
FACHBEREICH ELEKTROTECHNIK UND INFORMATIONSTECHNIK
BEREICH DATENTECHNIK
V – JV – 354 – 03 – TH – 01
-----------------------------------------------------------------------------------
Dateizugriff in Java (4-3)
• Demoprogramm zum Dateizugriff (Kopieren einer Datei)
// FileCopy.java
import java.io.*;
public class FileCopy
{
public static void main(String[] args)
{
if (args.length <2)
System.out.println("Aufruf : \"java FileCopy quelldatei zieldatei\"");
else
{
try
{
File ifile = new File(args[0]);
FileInputStream in = new FileInputStream(ifile);
FileOutputStream out = new FileOutputStream(args[1]);
long fsize = ifile.length();
System.out.print("Kopiert wird \"" + args[0]+ "\" (Laenge : ");
System.out.println(fsize + " Bytes) nach \"" + args[1]+ "\"");
byte[] buff = new byte[512];
int len;
while ((len=in.read(buff))>=0)
{
out.write(buff, 0, len);
}
out.close();
in.close();
System.out.println("Kopieren der Dateien erfolgreich");
}
catch(IOException ex)
{
System.out.println("Exception : " + ex.getMessage());
}
}
}
}
Beispiel für Programmaufruf und -ausgabe
E:\Java\fhm\ee\vorl\fileacc>java FileCopy ListDir.class ListDir.bin
Kopiert wird "ListDir.class" (Laenge : 1100 Bytes) nach "ListDir.bin"
Kopieren der Dateien erfolgreich
FACHHOCHSCHULE MUENCHEN
FACHBEREICH ELEKTROTECHNIK UND INFORMATIONSTECHNIK
FG TECHNISCHE INFORMATIK
V – JV – 355 – 01 – TH – 02
-----------------------------------------------------------------------------------
Dateizugriff in Java (5-1)
• Schreiben und Lesen von Daten in Binärdarstellung
◇ Dies wird durch die beiden Klassen DataOutputStream und DataInputStream ermöglicht
◇ Diese beiden Klassen implementieren jeweils ein Interface zum Schreiben bzw Lesen der internen Binärdarstellung
von Werten der einfachen Datentypen in bzw aus Streams und damit auch in bzw aus Dateien.
Zusätzlich ermöglichen sie eine effiziente Umcodierung zwischen 16-Bit-Unicode-Zeichen und Bytefolgen
für das Schreiben/Lesen von Strings (modifizierte UTF-8-Codierung)
◇ Objekte dieser Klassen wirken als Filter, die einen zugrundeliegenden Byte-Stream in geeigneter Weise umsetzen.
Eine Referenz auf das zu filternde Byte-Stream-Objekt ist ihrem Konstruktor als Parameter zu übergeben :
▻ public DataOutputStream(OutputStream out)
▻ public DataInputStream(InputStream in)
Das zu filternde Stream-Objekt kann natürlich auch ein Objekt der Klasse FileOutputStream (abgeleitet von
OutputStream) bzw FileInputStream (abgeleitet von InputStream) sein.
DataInputStream
FileInputStream
◇ Wichtigste Methoden der von DataOutputStream bzw DataInputStream implementierten Interfaces :
DataOutputStream
(Schreiben)
void
void
void
void
void
void
void
void
void
void
void
writeBoolean(boolean b)
writeByte(int b)
writeChar(int c)
writeShort(int s)
writeInt(int i)
writeLong(long l)
writeFloat(float f)
writeDouble(double d)
writeBytes(String str)
writeChars(String str)
writeUTF(String str)
void write(int b)
void write(byte[] ba)
void write(byte[] ba,
int off, int len)
DataInputStream
(Lesen)
Datentyp
boolean readBoolean()
byte readByte()
char readChar()
short readShort()
int readInt()
long readLong()
float readFloat()
double readDouble()
----String readUTF()
boolean
byte
char
short
int
long
float
double
String als Byte-Folge
String als Char-Folge
String (UTF-8-Cod.)
int read()
int read(byte[] ba)
int read(byte[] ba,
int off, int len
byte
byte-Array
byte-Array (Länge
len ab Offset off)
Alle Methoden für den Stream-Zugriff werfen eine IOException, wenn ein I/O-Fehler auftritt.
Die meisten Lese-Methoden werfen beim vorzeitigen Erreichen des Stream-Endes eine EOFException
alle Methoden sind mit der throws-Klausel throws IOException definiert.
◇ Beide Klassen stellen noch weitere Methoden zum Stream-Zugriff zur Verfügung.
◇ Anmerkung zur modifizierten UTF-8-Codierung :
▻ UTF = Universal Transfer Format : effiziente Codierung von Unicode-Zeichen durch 1, 2 und 3 Bytes
▻ Zeichen zwischen '\u0001' und '\u007F' durch ein Byte : 01 ... 7F
Zeichen zwischen '\u0080' und '\u07FF' durch zwei Bytes : C2 80 ... DF BF
Zeichen zwischen '\u0800' und '\uFFFF' durch drei Bytes : E0 A0 80 ... EF BF BF
der NUL-Character (das Zeichen '\u0000')
durch zwei Bytes : C0 80
▻ writeUTF(str) schreibt vor der eigentlichen den String str codierenden Bytefolge deren Länge als
short-Wert (2 Bytes) in den Stream.
FACHHOCHSCHULE MUENCHEN
FACHBEREICH ELEKTROTECHNIK UND INFORMATIONSTECHNIK
BEREICH DATENTECHNIK
V – JV – 355 – 02 – TH – 02
-----------------------------------------------------------------------------------
Dateizugriff in Java (5-2)
• Demoprogramm zum Schreiben von Daten in Binärdarstelung
// DataStreamDemo.java
import java.io.*;
public class DataStreamDemo
{
public static String byteToHex(byte b)
{
String str = Integer.toHexString(b & 0x00FF);
if (str.length() == 1)
str = '0' + str;
return str;
}
public static void main(String[] args)
{
if (args.length <1)
System.out.println("Aufruf : \"java DataStreamDemo dateipfad\"");
else
{
try
{ File fil = new File(args[0]);
FileOutputStream fout = new FileOutputStream(fil);
DataOutputStream dout = new DataOutputStream(fout);
dout.writeBoolean(true);
dout.writeInt(124);
dout.writeDouble(3.14);
dout.writeUTF("Hallo Java-Freunde");
dout.writeUTF("\u007F\u0080\u07FF\u0800\uFFFF\u0000");
dout.close();
FileInputStream fin = new FileInputStream(fil);
System.out.println("Inhalt der Datei \"" + args[0] + "\" :");
int b;
int cnt = 0;
while((b=fin.read())!=-1)
{
cnt++;
String hex = byteToHex((byte)b);
System.out.print(hex + ' ');
if (cnt%25 == 0)
System.out.println();
}
System.out.println();
fin.close();
}
catch(IOException ex)
{
System.out.println("Exception : " + ex.getMessage());
}
}
}
}
Programmaufruf und -ausgabe
E:\Java\fhm\ee\vorl\fileacc>java DataStreamDemo demo.dat
Inhalt der Datei "demo.dat" :
01 00 00 00 7c 40 09 1e b8 51 eb 85 1f 00 12 48 61 6c 6c 6f 20 4a 61 76 61
2d 46 72 65 75 6e 64 65 00 0d 7f c2 80 df bf e0 a0 80 ef bf bf c0 80
FACHHOCHSCHULE MUENCHEN
FAKULTÄT FÜR ELEKTROTECHNIK UND INFORMATIONSTECHNIK
FG TECHNISCHE INFORMATIK
V – JV – 356 – 01 – TH – 03
------------------------------------------------------------------------------------
Dateizugriff in Java (6-1)
• Zugriff zu Textdateien
◇ Der Zugriff zu Textdateien erfolgt sinnvollerweise über puffernde Zeichen-Stream-Objekte.
Diese werden durch die Klassen BufferedWriter (abgeleitet von Writer) und BufferedReader (abgeleitet von Reader) zur Verfügung gestellt.
◇ Die Objekte beider Klassen kapseln jeweils ein anderes Writer- bzw Reader-Objekt.
Eine Referenz auf dieses ist dem jeweiligen Konstruktor als Parameter zu übergeben.
▻ public BufferedWriter(Writer out)
▻ public BufferedReader(Reader in)
Durch Verwendung eines FileWriter- (indirekt abgeleitet von Writer) bzw FileReader- (indirekt
abgeleitet von Reader) Objekts als Konstruktor-Parameter erhält man pufferende Zeichen-Stream-Objekte für
den Dateizugriff.
BufferedReader
FileReader
◇ Obige Konstruktoren erzeugen Zeichen-Stream-Objekte, deren Puffer eine Standard-Default-Größe besitzen.
Diese Grösse ist für die meisten Anwendungsfälle groß genug.
Es existieren aber auch Konstruktoren, denen die Puffergröße als zweiter Parameter zu übergeben ist.
◇ Methoden der Klassen BufferedWriter und BufferedReader
▻ Beide Klassen stellen alle Methoden des jeweiligen Stream-Zugriffs-Interfaces der Klassen FileWriter
bzw FileReader sowie die Methode close() zur Verfügung
▻ Darüberhinaus besitzen sie aber einige zusätzliche Memberfunktionen :
Methode
Wirkung
existiert für Klasse
void newLine()
Schreiben eines Zeilenendes
BufferedWriter
String readLine()
Lesen einer Zeile, Rückgabe als String
Rückgabe von null, wenn am Dateiende
BufferedReader
Auch diese Methoden werfen eine IOException, wenn ein I/O-Fehler auftritt.
sie sind mit der throws-Klausel throws IOException definiert.
▻ Zusätzlich verfügt die Klasse BufferedReader über Memberfunktionen zum Markieren und späteren
Wiedereinnehmen einer bestimmten Position im Stream.
• Weitere Stream-Filter-Klassen
◇ Im Package java.io sowie in einigen anderen Packages (z.B. java.util.zip) sind noch weitere StreamKlassen enthalten, die als Filter von anderen Stream-Objekten und damit auch von File-Stream-Objekten eingesetzt
werden können. Dadurch lassen sich File-Stream-Objekte mit weiteren speziellen Eigenschaften versehen.
◇ Beispiele :
FilterReader
LineNumberReader
PrintWriter
PrintStream
PushbackInputStream
CheckedOutputStream
abstrakte Basisklasse für – eigene – Reader-Filter-Klassen
Klasse zum zeilenorientierten Lesen aus Zeichen-Streams
Klasse zur Ausgabe der externen Darstellung von Datenwerten in Zeichen-Streams
Klasse zur Ausgabe der externen Darstellung von Datenwerten in Byte-Streams
Klasse, die die Rückgabe gelesener Bytes in einen Eingabe-Byte-Stream ermöglicht
Klasse, die an einen Ausgabe-Stream eine Prüfsumme anhängt.
FACHHOCHSCHULE MUENCHEN
FACHBEREICH ELEKTROTECHNIK UND INFORMATIONSTECHNIK
BEREICH DATENTECHNIK
V – JV – 356 – 02 – TH – 01
-----------------------------------------------------------------------------------
Dateizugriff in Java (6-2)
• Demoprogramm zum Zugriff zu Textdateien : Ausgabe einer Textdatei am Bildschirm
// TextFileList.java
import java.io.*;
public class TextFileList
{
public static void main(String[] args)
{
if (args.length <1)
System.out.println("Aufruf : \"java TextFileList dateipfad\"");
else
{
try
{
File fil = new File(args[0]);
if (!fil.exists())
System.out.println("Datei \"" + args[0] + "\" existiert nicht");
else
{
BufferedReader tf = new BufferedReader(new FileReader(args[0]));
String line;
while ((line=tf.readLine()) != null)
System.out.println(line);
tf.close();
}
}
catch(IOException ex)
{
System.out.println("Exception : " + ex.getMessage());
}
}
}
}
FACHHOCHSCHULE MUENCHEN
FAKULTÄT FÜR ELEKTROTECHNIK UND INFORMATIONSTECHNIK
FG TECHNISCHE INFORMATIK
V – JV – 356 – 03 – TH – 02
------------------------------------------------------------------------------------
Dateizugriff in Java (6-3)
• Formatiertes Schreiben in Textdateien (ab dem JDK 5.0)
◇ Mittels eines Objekts der Klasse Formatter
▻ Die Klasse Formatter (Package java.util) dient zum Erzeugen formatierter Textdarstellungen.
Formatter-Objekte können auch an Dateien gebunden werden. Damit lassen sie sich zur formatierten Ausgabe
in Textdateien einsetzen.
▻ Die jeweilige Datei ist durch Übergabe eines die Datei referierenden Objekts an den Konstruktor festzulegen.
Ein derartiges Objekt kann u.a. sein :
▹ Objekt der Klasse FileOutputStream
(z.B. Konstruktor Formatter(OutputStream os))
▸ Objekt der Klasse FileWriter
(z.B. Konstruktor Formatter(Appendable a))
▸ Objekt der Klasse File
(z.B. Konstruktor Formatter(File file))
Formatter
FileOutputStream
Formatter
FileWriter
Formatter
File
▻ Mit der Formatter-Methode
Formatter format(String format, Object... args)
kann formatierter Text in die Datei geschrieben werden.
Die Parameter entsprechen den Parametern der PrintStream-(und PrintWriter-) Methode printf() :
- format ist der anzuwendende Format-String
Syntax und Semantik des Format-Strings ist die gleiche wie beim Format-String der Methode printf()
- args sind die zu schreibenden (und in Textdarstellung umzuwandelnden) Werte
Rückgabewert : aktuelles Formatter-Objekt
▻ Beispiel :
public void formOutDouble1(String dpfad, int anz) throws IOException
{
File datei = new File(dpfad);
//Formatter form = new Formatter(datei);
//Formatter form = new Formatter(new FileOutputStream(datei));
Formatter form = new Formatter(new FileWriter(datei));
Random rand = new Random();
for (int j=1; j<=anz; ++j)
{
form.format("%.5f ", rand.nextDouble());
if (j%8==0)
form.format("%n");
}
form.close();
}
FACHHOCHSCHULE MUENCHEN
FACHBEREICH ELEKTROTECHNIK UND INFORMATIONSTECHNIK
FG TECHNISCHE INFORMATIK
V – JV – 356 – 04 – TH – 01
-----------------------------------------------------------------------------------
Dateizugriff in Java (6-4)
• Formatiertes Schreiben in Textdateien, Forts. (ab dem JDK 5.0)
◇ Mittels der PrintStream- (und PrintWriter-) Methode printf()
▻ Die – u.a. für die Standardausgabe eingesetzte –Klasse PrintStream ermöglicht die Ausgabe von Strings und
der externen Textdarstellung von Datenwerten in beliebige Byte-Streams, somit auch in Dateien.
▻ Analog dient die Klasse PrintWriter zur Ausgabe derartiger Informationen in Zeichen-Streams und damit
ebenfalls in entsprechende Dateien.
▻ Für beide Klassen ist die Datei bei der Objekt-Erzeugung durch Übergabe eines sie referierenden Objekts an den
jeweiligen Konstruktor festzulegen.
U.a. existieren die folgenden Konstruktoren :
▹ PrintStream(OutputStream os) (OutputStream ist u.a. Basisklasse von FileOutputStream)
▹ PrintStream(File file)
▹ PrintWriter(Writer out)
(Writer ist u.a. Basisklasse von FileWriter)
▹ PrintWriter(File file)
PrintStream
FileOutputStream
PrintStream
File
PrintWriter
FileWriter
PrintWriter
File
▻ Beide Klassen stellen ab dem JDK 5.0 zur formatierten Ausgabe die Memberfunktion printf() zur Verfügung
▹ Klasse PrintStream : PrintStream printf(String format, Object... args)
▹ Klasse PrintWriter : PrintWriter printf(String format, Object... args)
Beschreibung der Parameter sowie der Wirkungsweise der Funktion siehe "Standardausgabe - Formatierte Ausgabe"
▻ Beispiel :
public void formOutDouble2(String dpfad, int anz) throws IOException
{
File datei = new File(dpfad);
PrintStream prnt = new PrintStream(datei);
//PrintStream prnt = new PrintStream(new FileOutputStream(datei));
//PrintWriter prnt = new PrintWriter(datei);
//PrintWriter prnt = new PrintWriter(new FileWriter(datei));
Random rand = new Random();
for (int j=1; j<=anz; ++j)
{
prnt.printf("%.5f ", rand.nextDouble());
if (j%8==0)
prnt.printf("%n");
}
prnt.close();
}
FACHHOCHSCHULE MUENCHEN
FAKULTÄT ELEKTROTECHNIK UND INFORMATIONSTECHNIK
FG TECHNISCHE INFORMATIK
V – JV – 356 – 05 – TH – 02
-----------------------------------------------------------------------------------
Dateizugriff in Java (6-5)
• Formatiertes Lesen aus Textdateien (ab dem JDK 5.0)
◇ Hierfür lässt sich die Klasse Scanner einsetzen
◇ Scanner-Objekte dienen zum Zergliedern und Interpretieren von Zeichenfolgen. Diese Zeichenfolgen können
auch von Zeichen- und Byte-Streams und damit auch von Dateien geliefert werden.
◇ Die jeweilige Zeichenquelle ist einem Scanner-Objekt im Konstruktor zu übergeben, u.a. als Objekt der
▻ Klasse FileInputStream
(Konstruktor Scanner(InputStream source))
▻ Klasse FileReader
(Konstruktor Scanner(Readable source))
▻ Klasse File
(Konstruktor Scanner(File source))
Scanner
File *)
*)
bzw FileInputStream
oder FileReader
◇ Beschreibung der Funktionalität der Klasse Scanner siehe "Standard- Ein- und Ausgabe in Java".
◇ Beispiel :
Funktion zum Lesen aus Textdateien, deren Inhalt prinzipiell wie folgt aufgebaut ist.
Die gelesenen Werte werden im gleichen Format in die Standard-Ausgabe ausgegeben
(Memberfunktion der Klasse FormTextFileDemo)
2
3
1
6
3
:
:
:
:
:
0,44507
0,25472
0,96712
0,78277
0,54464
0,06490
0,13943
0,40664
0,24195
0,03770
0,54913
0,15014
0,99872
0,71365
0,14333
public void formInput() throws IOException
{
// String dpfad ist Datenkomponente der Klasse FormTextFileDemo
File datei = new File(dpfad);
Scanner scan = new Scanner(datei);
//Scanner scan = new Scanner(new FileInputStream(datei));
//Scanner scan = new Scanner(new FileReader(datei));
try
{
while (scan.hasNext())
{
int anz = scan.nextInt();
System.out.printf("%d : ", anz);
scan.next();
// Ueberlesen des ':'
double d;
for (int i = 1; i <= anz; ++i)
{
d = scan.nextDouble();
System.out.printf("%.5f ", d);
}
System.out.printf("%n");
}
}
catch (InputMismatchException ex)
{
System.err.println("Type Mismatch beim Lesen.");
}
scan.close();
}
FACHHOCHSCHULE MUENCHEN
FACHBEREICH ELEKTROTECHNIK UND INFORMATIONSTECHNIK
BEREICH DATENTECHNIK
V – JV – 357 – 01 – TH – 03
-----------------------------------------------------------------------------------
Dateizugriff in Java (7-1)
• Wahlfreier Zugriff zu Dateien
◇ Für den wahlfreien Zugriff zu Dateien steht die Klasse RandomAccessFile zur Verfügung.
Diese Klasse ist von keiner der File-Stream-Klassen sondern direkt von Object abgeleitet.
◇ Durch Objekte dieser Klasse können Dateien für einen wahlfreien Zugriff nur zum Lesen oder zum Lesen und
Schreiben geöffnet werden.
Der wahlfreie Zugriff wird durch die Möglichkeit zur expliziten Veränderung der aktuellen Bearbeitungsposition
(File-Pointer) realisiert.
◇ Konstruktoren der Klasse RandomAccessFile
▻ public RandomAccessFile(String path, String mode) throws FileNotFoundException
▻ public RandomAccessFile(File fil, String mode) throws FileNotFoundException
Der erste Parameter referiert die zu bearbeitende Datei (über den Zugriffspfad bzw ein File-Objekt, das diesen
repräsentiert)
Der zweite Parameter legt die Zugriffsart fest :
▻ "r" nur Lesen,
▻ "rw" Lesen und Schreiben. ("rws" und "rwd" sind auch zulässig)
Die Konstruktoren versuchen die referierte Datei für die angegebene Zugriffsart zu öffnen.
Falls die referierte Datei nicht existiert wird bei der Zugriffsart "rw" versucht, sie zu erzeugen.
Die Konstruktoren können die folgenden Exceptions werfen :
▻ FileNotFoundException, falls die referierte Datei nicht existiert (Zugriffsart "r") oder ein Directory ist
oder nicht erzeugt werden kann oder aus einem anderen Grund nicht geöffnet werden kann.
▻ SecurityException, falls für die vorgesehene Zugriffsart keine Berechtigung besteht
▻ IllegalArgumentException, falls ein nicht zulässiger String für die Zugriffsart angegeben wird.
◇ Methoden der Klasse RandomAccessFile zum Dateizugriff :
Die Klasse stellt für den Dateizugriff die gleichnamigen Methoden mit gleicher Signatur wie die Klassen
DataInputStream und DataOutputStream zur Verfügung.
Wie bei diesen Klassen werfen die Zugriffsmethoden eine IOException beim Auftritt eines I/O-Fehlers.
Die meisten Lesemethoden werfen darüber hinaus eine EOFException beim vorzeitigen Erreichen des Dateiendes
◇ Weitere Methoden der Klasse RandomAccessFile (Auswahl)
Methode
Wirkung
Setzen der Bearbeitungsposition auf pos Bytes nach dem Dateianfang
Rückgabe der aktuellen Bearbeitungsposition
(in Bytes bezogen auf den Dateianfang)
int skipBytes(int cnt) Versuch, die Bearbeitungsposition um cnt Bytes weiterzusetzen
Rückgabe der Anzahl Bytes, um die tatsächlich weitergesetzt wurde
void seek(long pos)
long getFilePointer()
String readLine()
Lesen der nächsten Zeile (=Rückgabewert), Bytes werden zu Zeichen
ergänzt (höherwertiges Byte == NUL-Byte)
long length()
Rückgabe der Dateilänge
FileDescriptor getFD() Rückgabe des assoziierten FileDescriptor-Objekts
void close()
Schliessen der Datei und Freigabe aller belegten Resourcen
Alle o.a. Methoden werfen eine IOException wenn ein I/O-Fehler auftritt.
sie sind mit der throws-Klausel throws IOException definiert.
FACHHOCHSCHULE MUENCHEN
FACHBEREICH ELEKTROTECHNIK UND INFORMATIONSTECHNIK
BEREICH DATENTECHNIK
V – JV – 357 – 02 – TH – 02
-----------------------------------------------------------------------------------
Dateizugriff in Java (7-2)
• Demoprogramm zum wahlfreien Dateizugriff
// RandAccDemo.java
// Zufallsgesteuerte Auswahl eines Spruches aus einer Textdatei mit Spruechen.
// Die einzelnen Sprueche sind jeweils durch eine Zeile,
// die nur das Zeichen '*' enthaelt, getrennt.
import java.io.*;
public class RandAccDemo
{
public static void main(String[] args)
{
try
{
RandomAccessFile raf = new RandomAccessFile("sprueche.txt", "r");
long pos = (long)(raf.length()*Math.random());
raf.seek(pos);
while((pos!=0) && ((char)raf.read()!='*'))
raf.seek(--pos);
int ch;
if (pos==0)
System.out.println();
while (((ch=raf.read())!=-1) && ((char)ch!='*'))
{
System.out.print((char)ch);
}
System.out.println();
raf.close();
}
catch (IOException ex)
{
System.out.println(ex);
}
}
}
Beispiele für Programmaufruf und -ausgabe
E:\Java\fhm\ee\vorl\fileacc>java RandAccDemo
Gut gehaengt ist besser als schlecht verheiratet.
E:\Java\fhm\ee\vorl\fileacc>java RandAccDemo
Es ist nicht genug, dass man redet,
man muss auch richtig reden.
E:\Java\fhm\ee\vorl\fileacc>java RandAccDemo
Ein Tor nur schliesst aus aeusserem Gehaben
getrost auf eines Menschen innere Gaben.
FACHHOCHSCHULE MUENCHEN
FAKULTÄT FÜR ELEKTROTECHNIK UND INFORMATIONSTECHNIK
BEREICH DATENTECHNIK
V – JV – 358 – 00 – TH – 01
------------------------------------------------------------------------------------
Dateizugriff in Java – Zusammenfassender Überblick
Datei- bzw Verwendungsart
Klasse
Konstruktorparameter
(Auswahl)
wichtige
Zugriffsmethoden
sequentieller byteweiser
Zugriff
FileInputStream
FileOutputStream
File-Objekt oder
Dateizugriffspfad
read()
write()
sequentieller zeichenweiser
Zugriff
FileReader
FileWriter
File-Objekt oder
Dateizugriffspfad
read()
write()
Lesen/Schreiben von
Daten in Binärdarstellung
DataInputStream
DataOutputStream
FileInputStream-Obj.
FileOutputStream-Obj.
readInt() usw
writeInt() usw
Lesen/Schreiben von
Textdateien
BufferedReader
FileReader-Objekt
read()
readLine()
BufferedWriter
FileWriter-Objekt
write()
newLine()
Formatter
File-Objekt oder
FileWriter-Objekt oder
FileOutputStream-Obj
format()
PrintStream
File-Objekt oder
FileOutputStream-Obj
printf()
PrintWriter
File-Objekt oder
FileWriter-Objekt
printf()
Formatiertes Lesen
aus Textdateien
Scanner
File-Objekt oder
FileReader-Objekt oder
FileInputStream-Obj.
nextLine()
hasNextLine()
next()
hasNext()
nextInt() usw
wahlfreier Zugriff
RandomAccessFile
File-Objekt oder
Dateizugriffspfad
+ Zugriffsmodus (String)
seek()
getFilePointer()
skipBytes()
read()
readLine()
readInt() usw
write()
writeInt() usw
length()
Formatiertes Schreiben
in Textdateien
Herunterladen