listFiles() ein Programm, welches den Verzeichnisinhalt
für c:\ auflistet. [winnt]. java MeinFileList c:\windows
Falls kein Pfad angegeben ist, sollte der Benutzerpfad genutzt werden. Den erhält
man über die Property System.getProperty("user.home").
DirObserver, die jede Sekunde die Anzahl
der Dateien auf dem Bildschirm ausgibt. Als Rumpf lässt sich nutzen:
class DirObserver implements Runnable
{
private String path; DirObserver( String path )
{
this.path = path;
}
public void run()
{
...
}
}Ein java.io.FilenameFilter filtert die Liste der Dateien eines Verzeichnisses nach beliebigen Kriterien aus.
ExtensionFileFilter, die Dateien
(und nur diese) mit einer bestimmten Endung aufnimmt. Möchte man alle Java-Dateien
in der Rückgabe haben, soll sich schreiben lassen: File dir = new File( "." );
String files[] = dir.list( new ExtensionFileFilter( new String[]{"java"} ) );
for ( int i = 0; i < files.length; ++i ) System.out.println( files[i] );
new ExtensionFileFilter( "java" )
Unter der Win32-API gibt es Funktionen zum Suchen von Dateien. Leider gibt es
unter Java in den Bibliotheken keine dieser Funktionen. Implementiere eine Methode
String findFile(String path, String filename), die das Verzeichnissystem
rekursiv durchsucht und bei einem ersten Treffer den Gesamtpfad zurückgibt.
Die Datei Family-Names enthält
Familiennamen. Speichere die Datei auf dem eigenen Dateisystem. Lies die Datei mit
der readLine()-Methode aus
java.io.RandomAccessFile
ein und gib die Zeilen auf dem Bildschirm aus.
java.util.Arrays.
Eine Datei soll Byte für Byte umgedreht ausgegeben werden.
Wir haben schon einmal eine Klasse EMailSpeicher implementiert,
die Namen von Personen mit E-Mail-Adressen speichert. Erweitere die Klasse, damit
die Namen und Adressen jetzt aus einer Datei gelesen werden können. Lege dazu eine
Datei an mit Einträgen im Dateisystem, etwa folgender Art:
Christian Ullenboom=rudy@weihnachtsmann.org
Fritzi Foppel will nur die letzten 20 Zeilen aus einer Datei auf dem Bildschirm ausgeben. Wie kann er das effizient lösen?
Öffne ein java.io.FileOutputStream und schreibe die Buchstaben A, B, C hinein.
static
boolean fileCopy(String sourceFile, String destFile). Fehler sollen innerhalb
der Methode aufgefangen werden, aber die Rückgabe ist true, falls
es keine Fehler gab, und false, falls Fehler auftraten. insertFile(String
filename), die eine solche Darstellung erzeugt. Möchte man eine große Datei auf Diskette kopieren, dann besteht bei Dateien über 1,44 MB ein Problem. Man könnte dann aus einer großen Datei mehrere kleine "diskettenkompatible" machen. Schreibe für das Problem ein Programm, welches sich etwa so auf der Kommandozeile aufrufen lässt:
$ java Filesplit Datei.exe
War zum Beispiel die Datei 2,44 MB groß, dann könnte das Programm daraus die Dateien Datei1 und Datei2 mit den Größen 1,44 MB und 1 MB machen.
Erweiterung: Teste, ob das Aufzuspaltende eine Datei oder ein Verzeichnis ist. Ist es ein Verzeichnis, so komprimiere es mit dem ZIP-Format und spalte es anschließend auf.
Betrachte die Implementierung der
Was kann man über die Methode read() in
java.io.InputStream
und write() in
java.io.OutputStream
sagen? Warum sind einige der Methoden nicht abstrakt? Welche Konsequenz hat diesfür
die erbenden Klassen?
Schreibe mit Hilfe eines java.io.DataOutputStream in einen java.io.FileOutputStream ein paar primitive Datentypen und Zeichenketten.
Erstelle eine komprimierte und eine unkomprimierte Datei mit Zahlen von eins
bis X, die mit writeLong() in einen
java.util.zip.GZIPOutputStream geschrieben werden. Vergleiche die Dateigrößen.
Ab welchem x lohnt sich eine Kompression?
Implementiere einen Datenstrom mit einer neuen Klasse SnifferOutputStream,
der zwischen anderen Strömen gesetzt werden kann und alle Daten intern speichert.
Gebe dem Sniffer eine Methode reset(), die den Inhalt zurücksetzt,
und eine Methode getContent(), die den bis dahin gespeicherten Inhalt
liefert. Der Sniffer ist von
java.io.FilterOutputStream abgeleitet. Einzusetzen ist er etwa wie folgt:
OutputStream sos = new SnifferOutputStream( new FileOutputStream("huhu.txt") );
DataOutputStream dos = new DataOutputStream( sos );
dos.writeChars( "Hallo Leute" );
System.out.println( ((SnifferOutputStream)sos).getContent() );
Lege eine Datei mit einem java.io.FileOutputStream an. Erzeuge anschließend einen java.io.PrintStream (oder java.io.PrintWriter) und schreibe einige Zeilen Text hinein.
close() am Ende vergisst? Was ist der Unterschied zwischen
java.io.PrintStream
und dem
java.io.DataOutputStream?
Implementiere eine Klasse, die den
java.io.PrintWriter
testet. In eine Datei sollen Zahlen von 1 bis 10 geschrieben werden.
random() aus
java.lang.Math
. Nutze einen java.io.BufferedReader, um so Zeilen mit Punkten zu lesen. Die Datei sieht etwa so aus:
1,2 9,43 2,3 42,3
Diese Zeilen können mit einem java.util.StringTokenizer auseinander genommen werden. Sie sollen als java.awt.Point-Objekte in eine java.util.ArrayList gehängt werden.
int main(void)
{
int c,i=0;
printf("unsigned char data[]=
{
\n");
while((c=getchar())!=EOF) { printf("%d, ", c);
if(((++i)&15)==0) printf("\n");
}
return 0;
}
Welche Streams enthalten andere Streams und wozu? Warum gibt es Byte- und Character-Streams?
Zu welcher der beiden Kategorien gehört in in
java.lang.System
und warum? Wie erzeuge ich einen Character-Stream, der den Inhalt von mehreren Dateien
als einen gepufferten Datenstrom zur Verfügung stellt? Wie kann man vorgehen, wenn
man zusätzlich Daten zurück in den Datenfluss bekommen will?
Verstehe die Klasse java.util.StringTokenizer, und implementiere ein cut(1)-ähnliches Java-Programm. Das Programm sollte gemäß folgender Syntax aufgerufen werden:
java Cut [-f field-list] [-d delims] [file ...]
field-list ist eine durch Kommata getrennte Liste von Ziffern. Jedes Zeichen in dem an das Java-Programm übergebenen String delims wird als ein Feldtrenner betrachtet.
Ein Aufruf könnte wie folgt aussehen:
$ cat input eins zwei drei eins und:zwei und:drei und: $ java Cut -f '2,1,2' -d ': ' input zwei eins zwei und eins und
Die field-list ist durch Kommata getrennt. Allerdings kann man nicht davon ausgehen, dass alle Elemente in dieser Liste positiv sind, dass die Anzahl kleiner als eine Konstante im Programm und die Syntax des Aufrufs korrekt ist; sprich, das Programm muss mit fehlerhaften Optionen zurechtkommen.
Beschreibe die Funktionen quoteChar(int ch), eolIsSignificant(boolean
flag) der Klasse
java.io.StreamTokenizer
an einem Beispiel.
Mit den Funktionen der Klassen ByteToCharXXX- und CharToByteXXX (XXX steht für den Encoding-Namen) der Pakete sun.io sind Konvertierungen von Datentypen möglich. Teste einige der Klassen mit folgendem Gerüst:
Writer out = new OutputStreamWriter(new FileOutputStream("Datei"), "Cp273");
out.write("äöüÄÖÜß§");
out.close();
oder
myStringLC = "äöüÄÖÜß§";
myByteArray = myStringLC.getBytes();
String encodedStr273 = new String(myByteArray, "Cp273");
System.out.println("encodedStr273 is " + encodedStr273);
Achtung! Wird eine nicht unterstützte Codepage benutzt, z.B. cp274, wird nicht etwa ClassNotFoundException ausgegeben, da es die entsprechende Klasse sun.io.ByteToCharCpxxx bzw. sun.io.CharToByteCPxxx nicht gibt, sondern UnsupportedEncodingException.
Schreibe eine Klasse JavaGreep, die in einer Datei nach einem Wort
sucht. Es soll für jedes Vorkommen die Zeilennummer ausgegeben werden.
Lies einen Text ein und untersuche die Häufigkeiten der vorkommenden Zeichen.
toString() soll eine prozentuale Tabelle mit Buchstabenhäufigkeiten
ausgeben.
java.util.zip.ZipFile
und
java.util.zip.ZipEntry.
java.util.HashMap-Objekt
serialisiert. Anschließend schreibe ein Programm, welches die
java.util.HashMap
wieder ausliest. Long-Objekte, so
lohnt sich ab einer bestimmten Anzahl von geschriebenen Elementen die Komprimierung.
Schiebe einen
java.util.zip.GZIPOutputStream zwischen
java.io.FileOutputStream und
java.io.ObjectOutputStream . Lösung für das Schreiben und Lesen einer komprimierten HashMap