15 Dateien

Werbung
Übungsblatt 9
15
Dateien
Machen Sie nun ein neues Paket mit dem Namen fileio. Da werden Sie alle Klassen von dieser
Übung schreiben. Machen Sie da eine neue Klasse: Test.java. Da sollen Sie danach die Paketen
java.util.*; und java.io.*; importieren und die folgende Methode schreiben:
1: public static void readLines(String fileName) throws Throwable {
2: File file = new File(fileName);
3: Scanner fin = new Scanner(file);
4: while(fin.hasNextLine()) {
5:
System.out.println(fin.nextLine());
6: }
7: fin.close();
8: }
Diese Methode liest den Inhalt der genannten Datei Zeile für Zeile, solange es weiteren Zeilen
in der Datei gibt. Jede Zeile wird gerade ausgedruckt, nachdem sie gelesen wurde. In der Zeile 2
des Programmstücks wird eine Repräsentation der Datei mit gegebenem Dateinamen erzeugt. Sehen
Sie java.sun.com19 für mehr Informationen über dem Typ File. In der Zeile 3 wird ein Scanner
erzeugt, der zum Lesen dieser Datei benutzt wird.
Die Methode hasNextLine() (Zeile 4) liefert true zurück, wenn man eine weitere Zeile aus der
Datei lesen kann, sonst false. Mit der Methode nextLine() (Zeile 5) bekommt man die nächste
noch nicht gelesene Zeile als ein String und ohne Zeilenumbruch.
Die Anweisung „throws Throwable“ (Zeile 1) bedeutet, dass unser Code Ausnahmen werfen
könnte, welches normalerweise mit einer try-catch Anweisung behandeln wird. Da Ausnahmen
aber kein Thema dieser Übung sind, wird diese Anweisung bei jeder Methode stehen, die eine Datei mit Scanner liest, oder solche eine Methode ruft.
Nun können Sie eine Datei test.txt in der Basisdatenverzeichnis des Projekts machen (Rechtklick
auf den Namen des Projekts in Package Explorer; New -> File auswählen; den Namen eingeben
und den Finish-Knopf klicken). Schreiben Sie ein Paar Zeilen in dieser Datei und speichern Sie
sie. Nun kehren Sie zurück zur Ihren Klasse und schreiben Sie die Methode main:
public static void main(String[] args) throws Throwable {
readLines("test.txt");
}
Nachdem Sie die Klasse rennen, sollen Sie den Inhalt der Datei auf stdout bekommen.
19
http://java.sun.com/j2se/1.5.0/docs/api/java/io/File.html
26
15.1
Input filtrieren
5a:
5b:
5c:
5d:
String line = fin.nextLine();
if(line.length() <= 80) {
System.out.println(line);
}
Hier speichert man Zuerst die gelesene Zeile in einem String line und danach druckt man
diesen String aus, nur wenn seine Länge kleiner oder gleich 80 ist. Mit der Bedingung in der Zeile
5b kann man also entscheiden welche Zeilen enier Datei zu verarbeien sind. Zum Beispiel können
wir auch unsere neue Methode kopieren, die Kopie als readLinesWithAWord nennen und die Zeile
5b so ändern:
5b:
if(line.contains("test")) {
Dann werden nur die Zeilen ausgedruckt, die einen Teilstring "test" enthalten.
15.2
Andere Typen
Ausser den Zeilen, können wir mit der Klasse Scanner auch andere Tokens wie ein Wort (next()),
ein Integer (nextInt()) oder ein Double (nextDouble()) lesen. Wenn wir zum Beispiel unsere
letzte Methode kopieren, die Kopie sumNumbers nennen, und sie ab Zeile 4 so schreiben:
4:
5:
6:
7:
8:
9:
int sum = 0;
while(fin.hasNextInt()) {
sum += fin.nextInt();
}
fin.close();
System.out.println(sum);
Dann wird diese Methode die ganze Zahlen aus einer Datei lesen und ihre Summe auf stdout
ausdrucken. Es kann mehrere Zahlen in einer Zeile geben aber die einzige erlaubte Separatoren sind
Zwischenraumzeichen (auf engl. whitespaces). Wenn Scanner nach der zuletzt gelesener Zahl keine
Zahl mahr findet, wird hasNextInt schon false zurückliefern. Wenn man die Zahlen als Objekte
speichern will, muss man statt primitiven Datentypen int und double die Klassen Integer und
Dobule verwenden. Es folgt ein Beispiel, wo man die Zahlen aus einer Datei sortiert druckt:
public static void sortNumbers(String fileName) throws Throwable {
File file = new File(fileName); // Alles initialisieren
Scanner fin = new Scanner(file);
ArrayList<Integer> numbers = new ArrayList<Integer>();
while(fin.hasNextInt()) {
// Die Zahlen lesen und speichern
numbers.add(fin.nextInt());
}
fin.close();
// Die Datei so früh wie möglich schlieÿen
Collections.sort(numbers);
// Sortieren
for(Integer number : numbers) { // Oder "int number". Hier ist es schon egal.
System.out.println(number);
}
}
27
Autor: M. A.
Nun möchten wir unsere Aufgabe erweitern. Machen Sie eine Kopie dieser Methode, und nennen
Sie sie readLines80. Modifizieren Sie danach in dieser Methode den Körper von while:
15.3
Die Klasse String
Damit Sie die Eingabe von einer Datei bequem verarbeiten können, sollen Sie die Klasse String20
beherrschen. Hier werden einige Funktionalitäten angegeben.
Methode
Beschreibung / Ergebnis
char charAt(int pos)
Zeichen auf der Position pos.
int compareTo(String str)
Lexikographischer Vergleich mit str. Wie strcmp in C.
boolean contains(CharSequence s) Liefert true, wenn der String s enthalten ist.
boolean equals(Object obj)
Vergleich zum anderen Objekt obj (kann auch String
sein).
int indexOf(String str)
Index des ersten Vorvalls von str. Wenn es keinen gibt,
wird -1 zurückgeliefert.
int indexOf(String str, int pos) Index des ersten Vorvalls von str ab Position pos.
int length()
Länge des Strings.
String replace(String from,
Erzeugt eine Kopie des Strings, bei der alle "from" TeilString to)
strings mit "to" ersetzt sind.
String substring(int begin)
Erzeugt eine Kopie des Teilstrings, der auf der Position
begin beginnt.
String substring(int begin, int
Erzeugt eine Kopie des Teilstrings, der unter Indexe
end)
[begin, end) liegt.
String toLowerCase()
Erzeugt eine Kopie des Strings in Kleinschrift.
String toUpperCase()
Erzeugt eine Kopie des Strings in Großschrift.
String trim()
Erzeugt eine Kopie des Strings ohne Zwischenraumzeichen am Beginn und am Ende.
Oft werden Sie ein Zusammenspiel von diesen und anderen Methoden benutzen, um das gewünschte
Ergebnis zu kriegen. Wenn Sie zum Beispiel brauchen, den ersten Buchstaben von String str groß
und alle andere Buchstaben klein zu machen, wird es so aussehen:
str = str.substring(0,1).toUpperCase() + str.substring(1).toLowerCase();
15.4
Schreiben zu einer Datei
Bevor wir mit den Aufgaben beginnen, wird es noch kurz angegeben, wie kann man zu einer Datei
schreiben. Beobachten Sie den folgenden Code:
public static void testWrite() throws Throwable {
FileWriter fstream = new FileWriter("out.txt"); // FileWriter aus java.io.*;
BufferedWriter out = new BufferedWriter(fstream); // BufferedWriter aus java.io.*;
out.write("Hallo");
out.close();
}
So werden Sie eine neue Datei out.txt mit dem Inhalt "Hallo" machen (oder eine alte überschreiben). Machen Sie eine Aktualisierung (refresh, F5) des Projektbaums, um diese Datei zu sehen.
Wenn Sie den vorherigen Inhalt der Datei nicht überschreiben wollen, geben Sie beim Konstruktor
von FileWriter als zweites Argument true ein.
FileWriter fstream = new FileWriter("out.txt", true);
20
http://java.sun.com/j2se/1.5.0/docs/api/java/lang/String.html
28
15.5
Aufgaben
Lösen Sie nun die folgende Aufgaben. Jede Aufgabe soll in einer eigenen Klasse geschrieben werden.
Jede Klasse soll die main-Methode zur Ausführung und eine statische loesung-Methode zur Lösung
haben. Die Namen der Dateien müssen Argumenten der Methode loesung sein. Man darf auch
Hilfsmethoden schreiben.
1. Klasse Mittelwert: Lesen Sie alle ganze Zahlen aus einer Datei und berechnen Sie ihres
arithmetische Mittel als eine reelle Zahl. Behandeln Side den Fall wenn es keine Zahl in der
Datei gibt.
2. Klasse DMatrix: Lesen Sie eine Quadratmatrix der reellen Zahlen aus einer Datei. In der Datei
wird zuerst die Dimension der Matrix und dann die Matrix selbst angegeben. Die Matrix soll
man als double[][] mat speichern. Drucken Sie diese Matrix auf stdout und behandeln Sie
ein Paar möglichen Fehler: (1) Wenn kein Integer am Anfang steht. (2) Wenn es nicht genug
Zahlen für die ganze Matrix gibt, füllen sie den Rest der Matrix mit Nullen aus.
3. Klasse PrintBackwards: Lesen Sie den Inhalt einer Datei Zeile für Zeile. Dabei ist Ihre
Aufgabe jede Zeile Rückwärts auf stdout auszudrucken. Zum Beispiel, wenn eine Eingabezeile
"abcdef" wäre, würde ihre Ausgabezeile "fedcba" lauten. Benutzen Sie dabei von der Klasse
String nur Methoden length() und charAt().
4. Klasse MergeFiles: Es sind die Namen von zwei Dateien gegeben. Sie sollen eine dritte
Datei erzeugen, in der Sie zuerst die erste und danach die zweite Datei abschreiben.
5. Klasse MixFiles: Es sind die Namen von zwei Dateien gegeben. Sie sollen eine dritte Datei
erzeugen, in der Sie wechselweise eine Zeile von der ersten Datei und eine Zeile von der
zweiten Datei abschreiben. Wenn eine Datei zu Ende kommt, schreiben Sie ihre Zeilen einfach
nicht weiter.
6. Klasse ExtractData: Es ist eine XML Datei gegeben, wo meist der Zeilen Format:
<bl title="Mathematik" />
haben. Ihre Aufgabe ist nur die Zeilen mit dem Teilstring "title=" zu verarbeiten. Aus jeder
solchen Zeile sollen Sie den Teilstring zwischen " und " ausziehen (dieser Teilstring bei der
obigen Zeile würde Mathematik lauten). Diese Teilstrings sollen Sie in eine andere Datei
schrieben, wobei jeder Teilstring in seiner eigenen Zeile ist. Es dürfen keine leere Zeilen
zwischen den vollen erscheinen.
29
Herunterladen