Dateizugriffe mit Java
Einige der folgenden Beispiele werfen kontrollierte Ausnahmen, die noch deklariert oder gefangen werden müssen.
Anlegen einer Textdatei in einer Zeile
Man beachte den doppelten inversen Schrägstrich!
- Anweisung
new java.io.FileWriter( "c:\\example.txt" ).append( "alpha" ).close();
- Aussprachehinweis
- close cloz
Lesen einer Textdatei in einer Zeile
- String-Ausdruck \A = Begin of input
new java.util.Scanner( new java.io.File( "file.txt" ) ).useDelimiter( "\\A" ).next()
\z oder \Z gehen wohl nicht immer zuverlässig
- String-Ausdruck mit \$ = ?
new java.util.Scanner( new java.io.File( "file.txt" ) ).useDelimiter( "\\$" ).next()
Schreiben und Starten einer Kommandodatei mit PrintWriter
Main.java
public class Main
{ public static void main( final java.lang.String[] args )
throws java.lang.Throwable
{ final java.io.File outFile = new java.io.File( "generated.bat" );
final java.io.PrintWriter out =
new java.io.PrintWriter( new java.io.FileOutputStream( outFile ), true );
for( int i = 0; i < 60; ++i )out.println
( "wget http://www.example.com/resource" + i + ".text" );
out.close();
if( java.awt.Desktop.isDesktopSupported() )
java.awt.Desktop.getDesktop().open( outFile ); }}
Übungsaufgabe »final java.io.PrintWriter out = new java.io.PrintWriter( new java.io.FileOutputStream( outFile ), true );« durch Einführung von Konstantendeklarationsanweisungen so auf mehrere Anweisungen aufteilen, daß jede Anweisung nur noch ein »new« enthält.
Übungsaufgabe statische Convenience-Methode schreiben, die Pfad akzeptiert und PrintWriter ergibt.
Hinweis: Es gibt einen convenience-Konstruktor, der einen String akzeptiert, aber er hat »false« fest eingebaut und erlaubt keine Angabe einer Codierung.
Rekursives Durchstreifen
Ein Programm, das alle druckbaren Zeichen aus Dateien eines Verzeichnisse (einschließlich der Unterverzeichnisse beliebiger Tiefe) ausgibt. Dabei ergab sich beim Schreiben auf natürliche Weise eine Zerlegung in kleine Methoden. Das Programm wurde von hierarchisch oben nach hierarchisch unten geschrieben, die Methoden sind aber im Quelltext von hierarchisch unten nach hierarchisch oben angeordnet. Das folgende Programm zeigt, wie eine größere Aufgabe in überschaubare kleine Methoden zerlegt werden kann. Außerdem zeigt es eine natürliche Anwendung rekursiver Aufrufe von Methoden.
Main.java
public final class Main
{ final long[] count = new long[ 256 ];final static java.lang.String segmentSeparator = java.io.File.separator;
public static java.lang.String nextPrintable( final java.util.Scanner file )
{ return file.findWithinHorizon( "[\\p{Graph}\\p{Space}]", 0 ); }public static boolean handlePrintable( final java.lang.String printable )
{ java.lang.System.out.print( printable );
return true; }public static boolean file( final java.util.Scanner file )
{ java.lang.String text = null;
while( null !=( text = nextPrintable( file )))
if( !handlePrintable( text ))break;
return true; }public static boolean file( final java.io.File file )
{ try { file( new java.util.Scanner( file )); }
catch( final java.io.FileNotFoundException fileNotFoundException )
{ java.lang.System.err.println( fileNotFoundException ); }
return true; }public static boolean nodirectory( final java.io.File object )
{ if( object.isFile() )file( object );
return true; }
public static boolean directory( final java.io.File directory )
{ for( final java.io.File entry : directory.listFiles() )
if( !object( entry ))break;
return true; }
public static boolean object( final java.io.File object )
{ if( object.isDirectory() )directory( object );
else nodirectory( object );
return true; }
public static boolean object( final java.lang.String object )
{ object( new java.io.File( object ));
return true; }
public static void main( final java.lang.String[] args )
{ object
( "C:" + segmentSeparator + "example" + segmentSeparator + "path" ); }}
Properties
Writer.java
public class Writer
{ public static void main( final java.lang.String[] args ) throws java.io.IOException
{ final java.util.Properties properties = new java.util.Properties();
properties.put( "sehr gut", "1" );
properties.put( "gut", "2" );
properties.put( "befriedigend", "3" );
properties.put( "ausreichend", "4" );
properties.put( "mangelhaft", "5" );
properties.put( "ungenuegend", "6" );properties.store( new java.io.FileOutputStream( "grades" ), "comment" ); }}
Reader.java
public class Reader
{ public static void main( final java.lang.String[] args ) throws java.io.IOException
{ final java.util.Properties properties = new java.util.Properties();
properties.load( new java.io.FileInputStream( "grades" ));
java.lang.System.out.println( properties ); }}
Export von Preferences
Main.java
public final class Main
{final static java.util.prefs.Preferences alpha
= java.util.prefs.Preferences.userRoot().node
( "/com/example/project/alpha/version/1" );public static void show()
{ java.lang.System.out.print( alpha.get( "string name", "default value" ) );
java.lang.System.out.println( ", " + alpha.getInt( "int name", 17 ) ); }public static void main( final java.lang.String[] args )
{ show();// alpha.put( "string name", "text" );
// alpha.putInt( "int name", 20 );force(); }}
Main.java
public final class Main
{final static java.util.prefs.Preferences alpha
= java.util.prefs.Preferences.userRoot().node
( "/com/example/project/alpha/version/1" );public static void show()
{ java.lang.System.out.print( alpha.get( "string name", "default value" ) );
java.lang.System.out.println( ", " + alpha.getInt( "int name", 17 ) ); }public static void force()
{ show();try { alpha.sync(); } /* future reads will show the values put */
catch( final java.util.prefs.BackingStoreException exception )
{ java.lang.System.err.println( exception ); }show();
try { alpha.flush(); } /* forces to store */
catch( final java.util.prefs.BackingStoreException exception )
{ java.lang.System.err.println( exception ); }show(); }
public static void main( final java.lang.String[] args )
{ show();alpha.put( "string name", "text" );
alpha.putInt( "int name", 20 ); force();try
{ alpha.exportSubtree( java.lang.System.out ); }
catch( final java.util.prefs.BackingStoreException exception )
{ java.lang.System.err.println( exception ); }
catch( final java.io.IOException exception )
{ java.lang.System.err.println( exception ); }try { alpha.removeNode(); }
catch( final java.util.prefs.BackingStoreException exception )
{ java.lang.System.err.println( exception ); }force(); }}
transcript
default value, 17
text, 20
text, 20
text, 20
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE preferences SYSTEM "http://java.sun.com/dtd/preferences.dtd">
<preferences EXTERNAL_XML_VERSION="1.0">
<root type="user">
<map/>
<node name="com">
<map/>
<node name="example">
<map/>
<node name="project">
<map/>
<node name="alpha">
<map/>
<node name="version">
<map/>
<node name="1">
<map>
<entry key="string name" value="text"/>
<entry key="int name" value="20"/>
</map>
</node>
</node>
</node>
</node>
</node>
</node>
</root>
</preferences>
Exception in thread "main" java.lang.IllegalStateException: Node has been removed.
at java.util.prefs.AbstractPreferences.get(AbstractPreferences.java:283)
at Main.show(Main.java:9)
at Main.force(Main.java:13)
at Main.main(Main.java:44)
Eventuell sollte zusätzlich noch eine Möglichkeit zum Export/Import der Informationen angegeboten werden, falls der Benutzer die Konfigurationsdaten selber sicher möchte.
prefs.exportSubtree(OutputStream os);
prefs.importPreferences(InputStream is)
Übungsaufgaben
Die Preferences sollen nicht mehr auf die Konsole, sondern auf in eine Datei auf der Festplatte geschrieben werden