Programmierkurs Kapitel 12 Allgemeine Konzepte 12.1 Byte

Werbung
Kapitel 12
Dateiein- und -ausgabe
Byte-Streams versus Character-Streams
Die abstrakte Klasse Writer
FileWriter
StringWriter und CharArrayWriter
BufferedWriter
PrintWriter
Die abstrakte Klasse Reader
FileReader
StringReader und CharArrayReader
BufferedReader
Datei- und Verzeichnis-Handling
Programmierkurs
Birgit Engels
Anna Schulze
Zentrum für Angewandte Informatik
Köln
WS 07/08
1 / 43
2 / 43
Allgemeine Konzepte
Es gibt eine umfangreiche Bibliothek zum Zugriff auf Dateien
und zur Verwaltung von Verzeichnissen.
Die Klassen realisieren dabei das Konzept der Streams mit
Hilfe objektorientierter Techniken.
12.1 Byte-Streams versus Character-Streams
Die Klassen können vom Anwender erweitert werden
Alle Klassen zur Dateiein-und -ausgabe befinden sich im Paket
java.io.
Um sie zu verwenden, muss am Anfang eines Programms
import java.io.* aufgerufen werden
3 / 43
4 / 43
Byte-Streams versus Character-Streams
Character-Streams
Bis zur Version 1.0 des JDK gab es nur Byte-Streams
Wesentliches Merkmal von Byte-Streams: Es wurden 8 Bit zur
Speicherung eines Zeichens verwendet
Eine Klasse für den lesenden Zugriff wird als Reader
bezeichnet
Java verwendet aber sonst 16 Bit lange Unicode-Zeichen
Wesentliches Merkmal von Charakter-Streams: Es werden 16
Bit lange Unicode-Zeichen verwendet.
Eine Klasse für den schreibenden Zugriff wird als Writer
bezeichnet
Dadurch wesentlich besser Kompatibilität zu String- und
anderen Zeichentypen
Es gibt Klassen, die Character-Streams in Byte-Streams
überführen und umgekehrt
Wir beschäftigen uns ausschließlich mit Character-Streams
5 / 43
6 / 43
Die abstrakte Klasse Writer
Konstruktor (öffnet Ausgabestrom):
protected Writer()
Schließen des Ausgabestroms:
public void close() throws IOException
12.2 Die abstrakte Klasse Writer
Ein Zeichen schreiben:
public void write(int c) throws IOException
Mehrere Zeichen schreiben:
public void write(char cbuf[]) throws IOException
Ein String schreiben:
public void write(String s) throws IOException
7 / 43
8 / 43
Abgeleitete Klassen
FileWriter
Zusätzliche Methoden der Klasse FileWriter:
public FileWriter(String fileName) throws
IOException
public FileWriter(String fileName, boolean
append) throws IOException
public FileWriter(File file) throws IOException
Es kann kein Objekt der abstraken Klasse Writer erstellt werden.
Die abgeleiteten Klassen stellen eine Verbindung zu einem
konkreten Ausgabegerät her und implementieren die Methoden der
Klasse Writer:
FileWriter: Ausgabe in eine Datei
StringWriter: Writer zur Ausgabe in einen String
Falls filename eine bereits vorhandene Datei bezeichnet,
wird sie geöffnet und gelöscht.
Andernfalls wird eine Datei dieses Namens angelegt und
geöffnet.
Wird der Parameter append mit dem Wert true übergeben,
so wird die Datei nicht gelöscht.
Im Abschnitt 12.11 gehen wir auf die Klasse File ein
CharArrayWriter: Writer zur Ausgabe in ein Zeichen-Array
BufferedWriter: Writer zur Ausgabepufferung
PrintWriter: Ausgabe aller Basistypen im Textformat
9 / 43
10 / 43
StringWriter und CharArrayWriter
FileWriter
import java.io.*;
public class MyFileWriter {
public static void main(String[] args) {
FileWriter f1;
try
{
f1 = new FileWriter(‘‘hallo.txt’’, true);
f1.write(‘‘hello\n’’);
f1.close();
}
catch(IOException e)
{
Im Gegensatz Klasse FileWriter schreiben StringWriter und
CharArrayWriter ihre Ausgabe nicht in eine Datei, sondern in ein
StringBuffer bzw. Character-Array:
System.out.println(‘‘Fehler beim Erstellen der Datei’’);
}
}
}
11 / 43
12 / 43
StringWriter
StringWriter
import java.io.*;
public class MyStringWriter {
public static void main(String[] args) {
String hello;
StringWriter s1;
try {
s1 = new StringWriter();
s1.write(‘‘Hello Java!’’);
hello = s1.toString();
s1.close();
System.out.println(hello);
}
catch(IOException e) {
Der Konstruktor legt einen StringBuffer an:
public StringWriter()
Zugriff auf den Inhalt des Puffers:
public StringBuffer getBuffer()
public String toString()
System.out.println(‘‘Fehler beim Erstellen der Datei’’);
}
}
13 / 43
CharArrayWriter
}
14 / 43
CharArrayWriter
Der Konstruktor legt einen Character-Array an, das dynamisch
wachsen kann:
Leeren des Puffers:
public CharArrayWriter()
public void reset()
Zugriff auf den Inhalt des Puffers:
Größe des Puffers:
public char[] toCharArray()
public String toString()
public int size()
Übergabe an einen Writer:
public void writeTo(Writer out) throws
IOException
15 / 43
16 / 43
BufferedWriter
BufferdWriter
Die Klasse BufferedWriter hat die Aufgabe,
Stream-Ausgaben zu puffern.
An den Konstruktor wird ein externer Writer übergeben, an den
die gepufferten Ausgaben weitergereicht werden:
Dazu hat sie einen internen Puffer, in dem die Ausgaben von
write zwischengespeichert werden
public BufferedWriter(Write out)
Wenn der Puffer voll ist oder die Methode flush aufgerufen
wird, werden alle gepufferten Ausgaben in den echten Stream
geschrieben.
Zeilenschaltung:
Das Puffern ist sinnvoll, wenn die Ausgabe in eine Datei
geschrieben wird.
public void newLine()
Es reduziert sich die Anzahl der Zugriffe auf das externe Gerät.
Die Performance wird erhöht.
17 / 43
BufferdWriter
import java.io.*;
public class MyBufferedWriter {
public static void main(String[] args)
{
Writer f1;
BufferedWriter f2;
String s;
try
{
...
}
catch(IOException e)
{
...
}
}
}
18 / 43
BufferdWriter
Writer f1;
BufferedWriter f2;
String s;
try {
f1 = new FileWriter(‘‘buffer.txt’’);
f2 = new BufferedWriter(f1);
for(int i=1; i<=10000;++i) {
s = ‘‘Dies ist die ’’ + i + ‘‘. Zeile\n’’;
f2.write(s);
}
f2.close();
f1.close();
}
catch(IOException e) {
System.out.println(‘‘Fehler beim Erstellen der Datei’’);
}
19 / 43
20 / 43
PrintWriter
PrintWriter
An den Konstruktor wird ein externer Writer übergeben, auf den
die Ausgaben umgeleitet wird:
public PrintWriter(Writer out)
Die Klasse PrintWriter hat die Aufgabe, primitive
Datentypen in textueller Form auszugeben
Die Ausgabe von primitiven Datentypen wird durch eine Reihe von
Methoden mit dem Namen print bzw. println realisiert:
public void print(boolean b)
public void print(int i)
...
21 / 43
22 / 43
PrintWriter
import java.io.*;
public class MyPrintWriter {
public static void main(String[] args) {
PrintWriter f;
int antwort = 42;
try {
f = new PrintWriter(new BufferedWriter(
new FileWriter(‘‘test.txt’’)));
f.print(‘‘Die Antwort ist: ’’);
f.print(antwort);
f.close();
}
catch(IOException e) {
12.7 Die abstrakte Klasse Reader
System.out.println(‘‘Fehler beim Erstellen der Datei’’);
}
}
}
23 / 43
24 / 43
Die abstrakte Klasse Reader
Die abstrakte Klasse Reader
Konstruktor (öffnet Ausgabestrom):
ready liefert true, falls der nächste Aufruf von read erfolgreich
sein wird:
public Reader()
Schließen des Ausgabestroms:
public boolean ready()
public void close()
Eine Anzahl von Zeichen im Lesestrom überspringen
(Dabei kann es vorkommen, dass aus verschiedenen Gründen nicht
exakt die angegebene Anzahl übersprungen werden kann
Der Rückgabewert gibt die tatsächliche Anzahl an):
Ein Zeichen lesen, das als int zurück gegeben wird:
public int read()
Mehrere Zeichen in Variable cbuf[] einlesen und Anzahl der
gelesenen Zeichen zurück geben:
public long skip(long n)
public int read(char cbuf[])
25 / 43
Abgeleitete Klassen
26 / 43
FileReader
Es kann kein Objekt der abstraken Klasse Reader erstellt werden.
Die abgeleiteten Klassen stellen eine Verbindung zu einem
konkreten Einlesegerät her und implementieren die Methoden der
Klasse Reader:
Öffnen einer Datei:
FileReader: Einlesen aus einer Datei
public FileReader(String fileName) throws
FileNotFoundException
public FileReader(File file) throws
FileNotFoundException
StringReader: Reader zum Einlesen von Zeichen aus einem
String
CharArrayReader: Reader zum Einlesen von Zeichen aus
einem Character-Array
BufferedReader: Reader zur Eingabepufferung und zum
Lesen von kompletten Zeilen
LineNumberReader: Ableitung aus BufferedReader mit der
Fähigkeit Zeilen zu zählen
27 / 43
28 / 43
StringReader und CharArrayReader
StringWriter und CharArrayReader
Der Konstruktoren:
Im Gegensatz Klasse FileReader lesen StringReader und
CharArrayReader aus einem String bzw. Character-Array:
public StringReader(String s)
public CharArrayReader(char buf[])
29 / 43
BufferedReader
30 / 43
BufferdReader
Die Klasse BufferedReader hat die Aufgabe,
Stream-Eingaben zu puffern.
An den Konstruktor wird ein externer Reader übergeben, an den
die gepufferten Eingabe weitergereicht werden:
Dazu hat sie einen internen Puffer, in dem die Eingabe von
read zwischengespeichert werden
public BufferedReader(Reader in)
Wenn der Puffer voll ist oder die Methode flush aufgerufen
wird, werden alle gepufferten Eingaben in den echten Stream
geschrieben.
Eine ganze Zeile einlesen:
Das Puffern ist sinnvoll, wenn die Eingabe aus einer Datei
gelesen wird.
public String readLine() throws IOException
Es reduziert sich die Anzahl der Zugriffe auf das externe Gerät.
Die Performance wird erhöht.
31 / 43
32 / 43
LineNumber Reader
Ableitung von BufferedReader
Zählt die Anzahl der Eingabezeilen beim Einlesen
Schnittstelle entspricht der von BufferedReader
Zusätzliche Methoden
12.11 Datei- und Verzeichnis-Handling
Zeilennummber einlesen:
public int getLineNumber()
Zeilenzähler verändern:
public void setLineNumber(int lineNumber)
33 / 43
Die Klasse File
34 / 43
Die Klasse File
Die Klasse File kann als Abstraktion eines Dateinamens
angesehen werden.
File kann absolute und relative Namen unter UNIX Windows
repräsentieren.
Ein File objekt kann auch Verzeichnisse repräsentieren.
Konstruktoren
import java.io.*;
public class VerzeichnisHandling
{
public static void main(String[] args)
{
File testFile1 = new File(‘‘TestFile.txt’’);
File testFile2 = new File(‘‘/beispiele/’’,
‘‘TestFile2.txt’’);
}
}
Initialisierung eines File-Objekts zu dem angegebenen Datei- oder
Verzeichnisnamen:
public File(String pathname)
Initialisierung, wenn der Verzeichnis- und Dateiname getrennt
übergeben wird:
public File(String parent, String child)
public File(File parent, String child)
35 / 43
36 / 43
Verzeichnisnamen unter WINDOWS
Zugriff auf Teile des Pfadnamens
Wert der Variablen pathname bzw. child:
public String getName()
Unter WINDOWS ist der Backslash \ gleichzeitig
Escape-Zeichen für Strings, deswegen muss er in
Verzeichnisangaben doppelt angegeben werden.
Wert der Variablen pathname bzw. parent+child:
public String getPath()
Absoluter Pfadname:
new
File(‘‘c:\\Java\\Beispiele\\Backslash.java’’);
public String getAbsolutePath()
Namen des Vaterverzeichnisses:
public String getParent()
37 / 43
Zugriff auf Teile des Pfadnamens
public class VerzeichnisHandling
{
public static void pfadAusgabe(File file)
{
System.out.println(file.getName());
System.out.println(file.getPath());
System.out.println(file.getAbsolutePath());
}
public static void main(String[] args)
{
File testFile1 = new File(‘‘TestFile.txt’’);
File testFile2 = new File(‘‘/beispiele/’’,
‘‘TestFile2.txt’’);
pfadAusgabe(testFile1);
pfadAusgabe(testFile2);
}
}
38 / 43
Zugriff auf Teile des Pfadnamens
Ausgabe des Programms:
TestFile.txt
TestFile.txt
/beispiele/TestFile.txt
TestFile2.txt
/beispiele/TestFile2.txt
/beispiele/TestFile2.txt
39 / 43
40 / 43
Informationen über die Datei
Informationen über die Datei
Test der Existenz einer Datei:
Würde das Objekt mit absoluter Pfadangabe konstruiert:
public boolean exists()
public boolean isAbsolute()
Schreibender/Lesender Zugriffe möglich:
Zeitpunkt der letzten Änderung in Millisekunden seit dem 1.1.1970
Mit Hilfe eines Date-Objektes kann Datum und Uhrzeit bestimmt
werden:
public boolean canWrite()
public boolean canRead()
Versteckte Datei:
public long lastModified()
public boolean isHidden()
Anzahl der Zeichen in der Datei:
Ist Objekt Datei oder Verzeichnis:
public long length()
public boolean isFile()
public boolean isDirectory()
41 / 43
Zugriff auf Verzeichnisse
Wurde ein File-Objekt für ein Verzeichnis konstruiert, so stehen
weitere Methoden zur Verfügung.
Inhalt des Verzeichnisses:
public String[] list()
Anlegen eines Verzeichnisses:
public boolean mkdir()
Löschen einer Datei oder Verzeichnisses:
public boolean delete()
43 / 43
42 / 43
Herunterladen