diff options
| author | Sven Eisenhauer <sven@sven-eisenhauer.net> | 2023-11-10 15:11:48 +0100 |
|---|---|---|
| committer | Sven Eisenhauer <sven@sven-eisenhauer.net> | 2023-11-10 15:11:48 +0100 |
| commit | 33613a85afc4b1481367fbe92a17ee59c240250b (patch) | |
| tree | 670b842326116b376b505ec2263878912fca97e2 /Master/Reference Architectures and Patterns/hjp5/html/k100268.html | |
| download | Studium-master.tar.gz Studium-master.tar.bz2 | |
Diffstat (limited to 'Master/Reference Architectures and Patterns/hjp5/html/k100268.html')
| -rw-r--r-- | Master/Reference Architectures and Patterns/hjp5/html/k100268.html | 1187 |
1 files changed, 1187 insertions, 0 deletions
diff --git a/Master/Reference Architectures and Patterns/hjp5/html/k100268.html b/Master/Reference Architectures and Patterns/hjp5/html/k100268.html new file mode 100644 index 0000000..d5f6f9c --- /dev/null +++ b/Master/Reference Architectures and Patterns/hjp5/html/k100268.html @@ -0,0 +1,1187 @@ +<html>
+<head>
+<title>
+Handbuch der Java-Programmierung, 5. Auflage
+</title>
+</head>
+<body>
+<a name="startofbody"></a>
+<script language="JavaScript" src="hjp4lib.js">
+</script>
+<script language="JavaScript">
+installKbdHandler("97,#startofbody;101,#endofbody;116,cover.html;122,k100003.html;115,search.html;105,index.html;100,JDKDOCS;112,APIDOCS;104,k100265.html;106,k100267.html;107,k100269.html;108,k100271.html");
+</script>
+<table border=0 cellpadding=0 cellspacing=1 width="100%">
+<tr bgcolor="#EEFFCC">
+<td width="7%" align=center bgcolor="#DDCC99"><a href="cover.html"> Titel </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100003.html"> Inhalt </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="search.html"> Suchen </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="index.html"> Index </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/index.html" onClick="this.href=getDocIndex()"> DOC </a>
+<td align="right">Handbuch der Java-Programmierung, 5. Auflage
+<tr bgcolor="#EEFFCC">
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100265.html"> << </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100267.html"> < </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100269.html"> > </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100271.html"> >> </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/api/index.html" onClick="this.href=getApiIndex()"> API </a>
+<td align="right">Kapitel 42 - Datenbankzugriffe mit JDBC
+</table>
+<hr>
+
+
+<!-- Section -->
+<a name="dirdb"></a>
+<h2>42.3 Die DirDB-Beispieldatenbank </h2>
+<hr>
+<ul>
+<li><a href="k100268.html#dirdb">42.3 Die DirDB-Beispieldatenbank</a>
+<ul>
+<li><a href="k100268.html#sectlevel3id042003001">42.3.1 Anforderungen und Design</a>
+<li><a href="k100268.html#sectlevel3id042003002">42.3.2 Das Rahmenprogramm</a>
+<li><a href="k100268.html#verbindungherstellen">42.3.3 Die Verbindung zur Datenbank herstellen</a>
+<ul>
+<li><a href="k100268.html#sectlevel4id042003003001">Systemvoraussetzungen</a>
+</ul>
+<li><a href="k100268.html#sectlevel3id042003004">42.3.4 Anlegen und Füllen der Tabellen</a>
+<li><a href="k100268.html#zaehlenverzdateien">42.3.5 Zählen der Verzeichnisse und Dateien</a>
+<li><a href="k100268.html#sectlevel3id042003006">42.3.6 Suchen von Dateien und Verzeichnissen</a>
+<li><a href="k100268.html#sectlevel3id042003007">42.3.7 Die zehn größten Dateien</a>
+<li><a href="k100268.html#sectlevel3id042003008">42.3.8 Speicherverschwendung durch Clustering</a>
+</ul>
+</ul>
+<hr>
+
+
+<!-- Section -->
+<a name="sectlevel3id042003001"></a>
+<h3>42.3.1 Anforderungen und Design </h3>
+
+<p>
+In diesem Abschnitt wollen wir uns die zuvor eingeführten Konzepte
+in der Praxis ansehen. Dazu erzeugen wir eine einfache Datenbank <i>DirDB</i>,
+die Informationen zu Dateien und Verzeichnissen speichern kann. Über
+eine einfache Kommandozeilenschnittstelle können die Tabellen
+mit den Informationen aus dem lokalen Dateisystem gefüllt und
+auf unterschiedliche Weise abgefragt werden.
+
+<p>
+<i>DirDB</i> besitzt lediglich zwei Tabellen <i>dir</i> und <i>file</i>
+für Verzeichnisse und Dateien. Sie haben folgende Struktur: <a name="tableid042002"></a>
+
+<p>
+<table cols=3 border width=66%>
+
+<tr>
+<td valign=top align=left width=25%><b>Name </b></td>
+<td valign=top align=left width=25%><b>Typ </b></td>
+<td valign=top align=left width=50%><b>Bedeutung</b></td></tr>
+<tr>
+<td valign=top align=left>did </td>
+<td valign=top align=left>INT </td>
+<td valign=top align=left>Primärschlüssel</td></tr>
+<tr>
+<td valign=top align=left>dname </td>
+<td valign=top align=left>CHAR(100) </td>
+<td valign=top align=left>Verzeichnisname</td></tr>
+<tr>
+<td valign=top align=left>fatherdid </td>
+<td valign=top align=left>INT </td>
+<td valign=top align=left>Schlüssel Vaterverzeichnis</td></tr>
+<tr>
+<td valign=top align=left>entries </td>
+<td valign=top align=left>INT </td>
+<td valign=top align=left>Anzahl der Verzeichniseinträge</td></tr>
+</table>
+<p><i>
+Tabelle 42.2: Die Struktur der dir-Tabelle</i></p>
+<a name="tableid042003"></a>
+<p>
+<table cols=3 border width=66%>
+
+<tr>
+<td valign=top align=left width=25%><b>Name </b></td>
+<td valign=top align=left width=25%><b>Typ </b></td>
+<td valign=top align=left width=50%><b>Bedeutung</b></td></tr>
+<tr>
+<td valign=top align=left>fid </td>
+<td valign=top align=left>INT </td>
+<td valign=top align=left>Primärschlüssel</td></tr>
+<tr>
+<td valign=top align=left>did </td>
+<td valign=top align=left>INT </td>
+<td valign=top align=left>Zugehöriges Verzeichnis</td></tr>
+<tr>
+<td valign=top align=left>fname </td>
+<td valign=top align=left>CHAR(100) </td>
+<td valign=top align=left>Dateiname</td></tr>
+<tr>
+<td valign=top align=left>fsize </td>
+<td valign=top align=left>INT </td>
+<td valign=top align=left>Dateigröße</td></tr>
+<tr>
+<td valign=top align=left>fdate </td>
+<td valign=top align=left>DATE </td>
+<td valign=top align=left>Änderungsdatum</td></tr>
+<tr>
+<td valign=top align=left>ftime </td>
+<td valign=top align=left>TIME </td>
+<td valign=top align=left>Änderungszeit</td></tr>
+</table>
+<p><i>
+Tabelle 42.3: Die Struktur der file-Tabelle</i></p>
+
+<p>
+Beide Tabellen besitzen einen Primärschlüssel, der beim
+Anlegen eines neuen Satzes vom Programm vergeben wird. Die Struktur
+von <i>dir</i> ist baumartig; im Feld <i>fatherid</i> wird ein Verweis
+auf das Verzeichnis gehalten, in dem das aktuelle Verzeichnis enthalten
+ist. Dessen Wert ist im Startverzeichnis per Definition 0. Über
+den Fremdschlüssel <i>did</i> zeigt jeder Datensatz aus der <i>file</i>-Tabelle
+an, zu welchem Verzeichnis er gehört. Die Tabellen stehen demnach
+in einer 1:n-Beziehung zueinander. Auch die Tabelle <i>dir</i> steht
+in einer 1:n-Beziehung zu sich selbst. <a href="k100268.html#erdiagramm">Abbildung 42.1</a>
+zeigt ein vereinfachtes E/R-Diagramm des Tabellendesigns.
+<p>
+<a name="erdiagramm"></a>
+<img src="images/ERDirDB.gif">
+<p>
+
+<p><i>
+Abbildung 42.1: E/R-Diagramm für DirDB</i></p>
+
+<p>
+Das Programm <font color="#660099">DirDB.java</font> soll folgende
+Anforderungen erfüllen:
+<ul>
+<li>Es soll wahlweise mit <a name="ixa103096"><i>MS-Access</i></a>,
+<a name="ixa103097"><i>InstantDB</i></a> oder mit <a name="ixa103098"><i>HSQLDB</i></a>
+zusammenarbeiten.
+<li>Es soll folgende Befehle interpretieren:
+<ul>
+<li>Leeren der Datenbank und Einlesen eines vorgegebenen Verzeichnisses
+inkl. aller Unterverzeichnisse.
+<li>Zählen der Dateien und Verzeichnisse in der Datenbank.
+<li>Suchen beliebiger Dateien oder Verzeichnisse.
+<li>Anzeige der größten Dateien.
+<li>Berechnen des durch Clustering verschwendeten Festplattenplatzes.
+</ul>
+</ul>
+
+
+<!-- Section -->
+<a name="sectlevel3id042003002"></a>
+<h3>42.3.2 Das Rahmenprogramm </h3>
+
+<p>
+Wir implementieren eine Klasse <font color="#000077"><tt>DirDB</tt></font>,
+die (der Einfachheit halber) alle Funktionen mit Hilfe statischer
+Methoden realisiert. Die Klasse und ihre <a href="index_m.html#ixb100150"><font color=#000080><tt>main</tt></font></a>-Methode
+sehen so aus:
+<a name="dirdbrahmen"></a>
+
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#DDDDDD">
+<tr>
+<td valign=top>
+<font color="#000055">
+<pre>
+<font color="#555555">001 </font><font color="#0000AA">import</font> java.util.*;
+<font color="#555555">002 </font><font color="#0000AA">import</font> java.io.*;
+<font color="#555555">003 </font><font color="#0000AA">import</font> java.sql.*;
+<font color="#555555">004 </font><font color="#0000AA">import</font> java.text.*;
+<font color="#555555">005 </font><font color="#0000AA">import</font> gk.util.*;
+<font color="#555555">006 </font>
+<font color="#555555">007 </font><font color="#0000AA">public</font> <font color="#0000AA">class</font> DirDB
+<font color="#555555">008 </font>{
+<font color="#555555">009 </font> <font color="#00AA00">//---Constants-----------------------------------------------</font>
+<font color="#555555">010 </font> <font color="#0000AA">static</font> <font color="#006699">int</font> INSTANT185 = 1;
+<font color="#555555">011 </font> <font color="#0000AA">static</font> <font color="#006699">int</font> ACCESS95 = 2;
+<font color="#555555">012 </font> <font color="#0000AA">static</font> <font color="#006699">int</font> HSQLDB = 3;
+<font color="#555555">013 </font>
+<font color="#555555">014 </font> <font color="#00AA00">//---Pseudo constants----------------------------------------</font>
+<font color="#555555">015 </font> <font color="#0000AA">static</font> String FILESEP = System.getProperty(<font color="#0000FF">"file.separator"</font>);
+<font color="#555555">016 </font>
+<font color="#555555">017 </font> <font color="#00AA00">//---Static Variables----------------------------------------</font>
+<font color="#555555">018 </font> <font color="#0000AA">static</font> <font color="#006699">int</font> db = INSTANT185;
+<font color="#555555">019 </font> <font color="#0000AA">static</font> Connection con;
+<font color="#555555">020 </font> <font color="#0000AA">static</font> Statement stmt;
+<font color="#555555">021 </font> <font color="#0000AA">static</font> Statement stmt1;
+<font color="#555555">022 </font> <font color="#0000AA">static</font> DatabaseMetaData dmd;
+<font color="#555555">023 </font> <font color="#0000AA">static</font> <font color="#006699">int</font> nextdid = 1;
+<font color="#555555">024 </font> <font color="#0000AA">static</font> <font color="#006699">int</font> nextfid = 1;
+<font color="#555555">025 </font>
+<font color="#555555">026 </font> <font color="#00AA00">//---main-------------------------------------------------</font>
+<font color="#555555">027 </font> <font color="#0000AA">public</font> <font color="#0000AA">static</font> <font color="#006699">void</font> main(String[] args)
+<font color="#555555">028 </font> {
+<font color="#555555">029 </font> <font color="#0000AA">if</font> (args.length < 1) {
+<font color="#555555">030 </font> System.out.println(
+<font color="#555555">031 </font> <font color="#0000FF">"usage: java DirDB [A|I|H] <command> [<options>]"</font>
+<font color="#555555">032 </font> );
+<font color="#555555">033 </font> System.out.println(<font color="#0000FF">""</font>);
+<font color="#555555">034 </font> System.out.println(<font color="#0000FF">"command options"</font>);
+<font color="#555555">035 </font> System.out.println(<font color="#0000FF">"---------------------------------"</font>);
+<font color="#555555">036 </font> System.out.println(<font color="#0000FF">"POPULATE <directory>"</font>);
+<font color="#555555">037 </font> System.out.println(<font color="#0000FF">"COUNT"</font>);
+<font color="#555555">038 </font> System.out.println(<font color="#0000FF">"FINDFILE <name>"</font>);
+<font color="#555555">039 </font> System.out.println(<font color="#0000FF">"FINDDIR <name>"</font>);
+<font color="#555555">040 </font> System.out.println(<font color="#0000FF">"BIGGESTFILES <howmany>"</font>);
+<font color="#555555">041 </font> System.out.println(<font color="#0000FF">"CLUSTERING <clustersize>"</font>);
+<font color="#555555">042 </font> System.exit(1);
+<font color="#555555">043 </font> }
+<font color="#555555">044 </font> <font color="#0000AA">if</font> (args[0].equalsIgnoreCase(<font color="#0000FF">"A"</font>)) {
+<font color="#555555">045 </font> db = ACCESS95;
+<font color="#555555">046 </font> } <font color="#0000AA">else</font> <font color="#0000AA">if</font> (args[0].equalsIgnoreCase(<font color="#0000FF">"H"</font>)) {
+<font color="#555555">047 </font> db = HSQLDB;
+<font color="#555555">048 </font> }
+<font color="#555555">049 </font> <font color="#0000AA">try</font> {
+<font color="#555555">050 </font> <font color="#0000AA">if</font> (args[1].equalsIgnoreCase(<font color="#0000FF">"populate"</font>)) {
+<font color="#555555">051 </font> open();
+<font color="#555555">052 </font> createTables();
+<font color="#555555">053 </font> populate(args[2]);
+<font color="#555555">054 </font> close();
+<font color="#555555">055 </font> } <font color="#0000AA">else</font> <font color="#0000AA">if</font> (args[1].equalsIgnoreCase(<font color="#0000FF">"count"</font>)) {
+<font color="#555555">056 </font> open();
+<font color="#555555">057 </font> countRecords();
+<font color="#555555">058 </font> close();
+<font color="#555555">059 </font> } <font color="#0000AA">else</font> <font color="#0000AA">if</font> (args[1].equalsIgnoreCase(<font color="#0000FF">"findfile"</font>)) {
+<font color="#555555">060 </font> open();
+<font color="#555555">061 </font> findFile(args[2]);
+<font color="#555555">062 </font> close();
+<font color="#555555">063 </font> } <font color="#0000AA">else</font> <font color="#0000AA">if</font> (args[1].equalsIgnoreCase(<font color="#0000FF">"finddir"</font>)) {
+<font color="#555555">064 </font> open();
+<font color="#555555">065 </font> findDir(args[2]);
+<font color="#555555">066 </font> close();
+<font color="#555555">067 </font> } <font color="#0000AA">else</font> <font color="#0000AA">if</font> (args[1].equalsIgnoreCase(<font color="#0000FF">"biggestfiles"</font>)) {
+<font color="#555555">068 </font> open();
+<font color="#555555">069 </font> biggestFiles(Integer.parseInt(args[2]));
+<font color="#555555">070 </font> close();
+<font color="#555555">071 </font> } <font color="#0000AA">else</font> <font color="#0000AA">if</font> (args[1].equalsIgnoreCase(<font color="#0000FF">"clustering"</font>)) {
+<font color="#555555">072 </font> open();
+<font color="#555555">073 </font> clustering(Integer.parseInt(args[2]));
+<font color="#555555">074 </font> close();
+<font color="#555555">075 </font> }
+<font color="#555555">076 </font> } <font color="#0000AA">catch</font> (SQLException e) {
+<font color="#555555">077 </font> <font color="#0000AA">while</font> (e != <font color="#006699">null</font>) {
+<font color="#555555">078 </font> System.err.println(e.toString());
+<font color="#555555">079 </font> System.err.println(<font color="#0000FF">"SQL-State: "</font> + e.getSQLState());
+<font color="#555555">080 </font> System.err.println(<font color="#0000FF">"ErrorCode: "</font> + e.getErrorCode());
+<font color="#555555">081 </font> e = e.getNextException();
+<font color="#555555">082 </font> }
+<font color="#555555">083 </font> System.exit(1);
+<font color="#555555">084 </font> } <font color="#0000AA">catch</font> (Exception e) {
+<font color="#555555">085 </font> System.err.println(e.toString());
+<font color="#555555">086 </font> System.exit(1);
+<font color="#555555">087 </font> }
+<font color="#555555">088 </font> }
+<font color="#555555">089 </font>}</pre>
+</font>
+</td>
+</tr>
+</table>
+<i>
+Listing 42.2: Das Rahmenprogramm der DirDB-Datenbank</i></p>
+
+<p>
+In <a href="index_m.html#ixb100150"><font color=#000080><tt>main</tt></font></a>
+wird zunächst ein <i>usage</i>-Text definiert, der immer dann
+ausgegeben wird, wenn das Programm ohne Argumente gestartet wird.
+Die korrekte Aufrufsyntax ist:
+<font color="#000077">
+<pre>
+java DirDB [A|I|H] <command> [<options>]
+</pre>
+</font>
+
+<p>
+Nach dem Programmnamen folgt zunächst der Buchstabe »A«,
+»I« oder »H«, um anzugeben, ob die Access-, InstantDB-
+oder HSQLDB-Datenbank verwendet werden soll. Das nächste Argument
+gibt den Namen des gewünschten Kommandos an. In der folgenden
+verschachtelten Verzweigung werden gegebenenfalls weitere Argumente
+gelesen und die Methode zum Ausführen des Programms aufgerufen.
+Den Abschluss der <a href="index_m.html#ixb100150"><font color=#000080><tt>main</tt></font></a>-Methode
+bildet die Fehlerbehandlung, bei der die Ausnahmen des Typs <a href="index_s.html#ixb102244"><font color=#000080><tt>SQLException</tt></font></a>
+und <a href="index_e.html#ixb100577"><font color=#000080><tt>Exception</tt></font></a>
+getrennt behandelt werden.
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100%>
+<tr>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top width=1000>
+
+<p>
+Das vollständige Programm findet sich auf der DVD zum Buch unter
+dem Namen <font color="#660099">DirDB.java</font>. In diesem Abschnitt
+sind zwar auch alle Teile abgedruckt, sie finden sich jedoch nicht
+zusammenhängend wieder, sondern sind über die verschiedenen
+Unterabschnitte verteilt. Das importierte Paket <a name="ixa103099"><a href="index_g.html#ixb100621"><font color=#000080><tt>gk.util</tt></font></a></a>
+kann wie in <a href="k100085.html#zuspaketeeinbinden">Abschnitt 13.2.3</a>
+beschrieben installiert werden.</td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top>
+<table border=0 cellspacing=0 cellpadding=1 width=100% bgcolor="#000077">
+<tr>
+<td><font color="#FFFFFF"> Hinweis </font></td>
+</tr>
+</table>
+</td>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+</tr>
+</table>
+
+
+<!-- Section -->
+<a name="verbindungherstellen"></a>
+<h3>42.3.3 Die Verbindung zur Datenbank herstellen </h3>
+
+<p>
+Wie in <a href="k100268.html#dirdbrahmen">Listing 42.2</a> zu sehen
+ist, rufen alle Kommandos zunächst die Methode <font color="#000077"><tt>open</tt></font>
+zum Öffnen der Datenbank auf. Anschließend führen
+sie ihre spezifischen Kommandos aus und rufen dann <font color="#000077"><tt>close</tt></font>
+auf, um die Datenbank wieder zu schließen.
+
+<p>
+Beim Öffnen der Datenbank wird zunächst mit <a href="index_f.html#ixb102240"><font color=#000080><tt>Class.forName</tt></font></a>
+der passende Datenbanktreiber geladen und beim Treibermanager registriert.
+Anschließend besorgt das Programm ein <a href="index_c.html#ixb102245"><font color=#000080><tt>Connection</tt></font></a>-Objekt,
+das an die statische Variable <font color="#000077"><tt>con</tt></font>
+gebunden wird. An dieser Stelle sind die potentiellen Code-Unterschiede
+zwischen den beiden Datenbanken gut zu erkennen:
+<ul>
+<li>Während der Treibername für InstantDB die Bezeichnung
+<font color="#000077"><tt>jdbc.idbDriver</tt></font> hat, lautet er
+für die JDBC-ODBC-Bridge <font color="#000077"><tt>sun.jdbc.odbc.JdbcOdbcDriver</tt></font>
+und für HSQLDB <font color="#000077"><tt>org.hsqldb.jdbcDriver</tt></font>.
+<li>Der Connection-URL bei InstantDB ist "jdbc:idb=", gefolgt vom
+Namen einer Property-Datei, die zusätzliche Konfigurationsangaben
+enthält. Bei der JDBC-ODBC-Bridge beginnt der URL immer mit »jdbc:odbc«,
+gefolgt vom Namen der ODBC-Datenquelle. Bei HSQLDB beginnt er mit
+»jdbc:hsqldb:«, gefolgt vom Namen der Datenbank.
+</ul>
+<a name="jdbcconfig"></a>
+
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#DDDDDD">
+<tr>
+<td valign=top>
+<font color="#000055">
+<pre>
+<font color="#555555">001 </font><font color="#00AA00">/**
+<font color="#555555">002 </font> * Öffnet die Datenbank.
+<font color="#555555">003 </font> */</font>
+<font color="#555555">004 </font><font color="#0000AA">public</font> <font color="#0000AA">static</font> <font color="#006699">void</font> open()
+<font color="#555555">005 </font><font color="#0000AA">throws</font> Exception
+<font color="#555555">006 </font>{
+<font color="#555555">007 </font> <font color="#00AA00">//Treiber laden und Connection erzeugen</font>
+<font color="#555555">008 </font> <font color="#0000AA">if</font> (db == INSTANT185) {
+<font color="#555555">009 </font> Class.forName(<font color="#0000FF">"jdbc.idbDriver"</font>);
+<font color="#555555">010 </font> con = DriverManager.getConnection(
+<font color="#555555">011 </font> <font color="#0000FF">"jdbc:idb=dirdb.prp"</font>,
+<font color="#555555">012 </font> <font color="#0000AA">new</font> Properties()
+<font color="#555555">013 </font> );
+<font color="#555555">014 </font> } <font color="#0000AA">else</font> <font color="#0000AA">if</font> (db == HSQLDB) {
+<font color="#555555">015 </font> Class.forName(<font color="#0000FF">"org.hsqldb.jdbcDriver"</font>);
+<font color="#555555">016 </font> con = DriverManager.getConnection(
+<font color="#555555">017 </font> <font color="#0000FF">"jdbc:hsqldb:hsqldbtest"</font>,
+<font color="#555555">018 </font> <font color="#0000FF">"SA"</font>,
+<font color="#555555">019 </font> <font color="#0000FF">""</font>
+<font color="#555555">020 </font> );
+<font color="#555555">021 </font> } <font color="#0000AA">else</font> {
+<font color="#555555">022 </font> Class.forName(<font color="#0000FF">"sun.jdbc.odbc.JdbcOdbcDriver"</font>);
+<font color="#555555">023 </font> con = DriverManager.getConnection(<font color="#0000FF">"jdbc:odbc:DirDB"</font>);
+<font color="#555555">024 </font> }
+<font color="#555555">025 </font> <font color="#00AA00">//Metadaten ausgeben</font>
+<font color="#555555">026 </font> dmd = con.getMetaData();
+<font color="#555555">027 </font> System.out.println(<font color="#0000FF">""</font>);
+<font color="#555555">028 </font> System.out.println(<font color="#0000FF">"Connection URL: "</font> + dmd.getURL());
+<font color="#555555">029 </font> System.out.println(<font color="#0000FF">"Driver Name: "</font> + dmd.getDriverName());
+<font color="#555555">030 </font> System.out.println(<font color="#0000FF">"Driver Version: "</font> + dmd.getDriverVersion());
+<font color="#555555">031 </font> System.out.println(<font color="#0000FF">""</font>);
+<font color="#555555">032 </font> <font color="#00AA00">//Statementobjekte erzeugen</font>
+<font color="#555555">033 </font> stmt = con.createStatement();
+<font color="#555555">034 </font> stmt1 = con.createStatement();
+<font color="#555555">035 </font>}
+<font color="#555555">036 </font>
+<font color="#555555">037 </font><font color="#00AA00">/**
+<font color="#555555">038 </font> * Schließt die Datenbank.
+<font color="#555555">039 </font> */</font>
+<font color="#555555">040 </font><font color="#0000AA">public</font> <font color="#0000AA">static</font> <font color="#006699">void</font> close()
+<font color="#555555">041 </font><font color="#0000AA">throws</font> SQLException
+<font color="#555555">042 </font>{
+<font color="#555555">043 </font> stmt.close();
+<font color="#555555">044 </font> stmt1.close();
+<font color="#555555">045 </font> con.close();
+<font color="#555555">046 </font>}</pre>
+</font>
+</td>
+</tr>
+</table>
+<i>
+Listing 42.3: Öffnen und Schließen der DirDB-Datenbank</i></p>
+
+<p>
+Nachdem die Verbindung hergestellt wurde, liefert der Aufruf von <a name="ixa103100"><a href="index_g.html#ixb102279"><font color=#000080><tt>getMetaData</tt></font></a></a>
+ein Objekt des Typs <a name="ixa103101"><a href="index_d.html#ixb102280"><font color=#000080><tt>DatabaseMetaData</tt></font></a></a>.
+Es kann dazu verwendet werden, weitere Informationen über die
+Datenbank abzufragen. Wir geben lediglich den Connection-String und
+Versionsinformationen zu den geladenen Treibern aus. <a href="index_d.html#ixb102280"><font color=#000080><tt>DatabaseMetaData</tt></font></a>
+besitzt darüber hinaus noch viele weitere Variablen und Methoden,
+auf die wir hier nicht näher eingehen wollen. Am Ende von <font color="#000077"><tt>open</tt></font>
+erzeugt das Programm zwei <a href="index_s.html#ixb102247"><font color=#000080><tt>Statement</tt></font></a>-Objekte
+<font color="#000077"><tt>stmt</tt></font> und <font color="#000077"><tt>stmt1</tt></font>,
+die in den übrigen Methoden zum Ausführen der SQL-Befehle
+verwendet werden. Zum Schließen der Datenbank werden zunächst
+die beiden <a href="index_s.html#ixb102247"><font color=#000080><tt>Statement</tt></font></a>-Objekte
+und dann die Verbindung selbst geschlossen.
+
+<!-- Section -->
+
+<a name="sectlevel4id042003003001"></a>
+<h4>Systemvoraussetzungen </h4>
+
+<p>
+Um tatsächlich eine Verbindung zu einer der drei angegebenen
+Datenbanken herstellen zu können, müssen auf Systemebene
+die nötigen Voraussetzungen dafür geschaffen werden:
+<ul>
+<li>Soll auf eine ODBC-Datenquelle zugegriffen werden, muss diese
+unter Windows-Systemsteuerung mit Hilfe des Menüpunkts »ODBC-Datenquellen«
+zunächst eingerichtet werden. Im Falle von Microsoft Access ist
+eine »Benutzer-DSN« hinzuzufügen, in der als wichtigste
+Eigenschaften der gewünschte Name der Datenquelle sowie der Pfad
+der <font color="#660099">.mdb</font>-Datei angegeben werden müssen.
+In unserem Beispiel wird »DirDB« als Datenquellenname verwendet.
+Im Verzeichnis mit den Beispieldateien zum Buch befindet sich eine
+leere Datenbank <font color="#660099">emptydb.mdb</font>, die mit
+<i>Access 2000</i> erstellt wurde und für erste Experimente verwendet
+werden kann. Sie sollte zu den Access-ODBC-Treibern, die aktuellen
+Windows-Betriebssystemen beiliegen, kompatibel sein.
+<li>InstantDB und HSQLDB sind reine Java-Datenbanken, die ohne separat
+zu installierende Treiber betrieben werden können. Üblicherweise
+muss bei ihnen lediglich das zugehörige jar-Archiv in den <a href="index_c.html#ixb100143"><font color=#000080><tt>CLASSPATH</tt></font></a>
+aufgenommen werden, damit ein Java-Programm darauf zugreifen kann.
+InstantDB war früher frei verfügbar, gehört aber mittlerweile
+zu <i>Lutris Technologies</i>. Privatleute können es zu Forschungs-
+und Entwicklungszwecken immer noch frei downloaden. Die Homepage von
+InstantDB ist <a href="http://instantdb.tripod.com/old-site/index.html">http://instantdb.tripod.com/old-site/index.html</a>.
+HSQLDB ist der Nachfolger von <a name="ixa103102"><i>Hypersonic SQL</i></a>.
+Die Datenbank ist frei verfügbar und wird als <i>SourceForge</i>-Projekt
+weiterentwickelt. Ihre Homepage ist <a href="http://hsqldb.sourceforge.net/">http://hsqldb.sourceforge.net/</a>.
+</ul>
+
+
+<!-- Section -->
+<a name="sectlevel3id042003004"></a>
+<h3>42.3.4 Anlegen und Füllen der Tabellen </h3>
+
+<p>
+Unsere Anwendung geht davon aus, dass die Datenbank bereits angelegt
+ist, erstellt die nötigen Tabellen und Indexdateien aber selbst.
+Die dazu nötigen SQL-Befehle sind <font color="#000077"><tt>CREATE
+TABLE</tt></font> zum Anlegen einer Tabelle und <font color="#000077"><tt>CREATE
+INDEX</tt></font> zum Anlegen einer Indexdatei. Diese Befehle werden
+mit der Methode <a href="index_e.html#ixb102250"><font color=#000080><tt>executeUpdate</tt></font></a>
+des <a href="index_s.html#ixb102247"><font color=#000080><tt>Statement</tt></font></a>-Objekts
+ausgeführt, denn sie produzieren keine Ergebnismenge, sondern
+als DDL-Anweisungen lediglich den Rückgabewert 0. Das Anlegen
+der Tabellen erfolgt mit der Methode <font color="#000077"><tt>createTables</tt></font>:
+<a name="listingid042004"></a>
+
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#DDDDDD">
+<tr>
+<td valign=top>
+<font color="#000055">
+<pre>
+<font color="#555555">001 </font><font color="#00AA00">/**
+<font color="#555555">002 </font> * Legt die Tabellen an.
+<font color="#555555">003 </font> */</font>
+<font color="#555555">004 </font><font color="#0000AA">public</font> <font color="#0000AA">static</font> <font color="#006699">void</font> createTables()
+<font color="#555555">005 </font><font color="#0000AA">throws</font> SQLException
+<font color="#555555">006 </font>{
+<font color="#555555">007 </font> <font color="#00AA00">//Anlegen der Tabelle dir</font>
+<font color="#555555">008 </font> <font color="#0000AA">try</font> {
+<font color="#555555">009 </font> stmt.executeUpdate(<font color="#0000FF">"DROP TABLE dir"</font>);
+<font color="#555555">010 </font> } <font color="#0000AA">catch</font> (SQLException e) {
+<font color="#555555">011 </font> <font color="#00AA00">//Nichts zu tun</font>
+<font color="#555555">012 </font> }
+<font color="#555555">013 </font> stmt.executeUpdate(<font color="#0000FF">"CREATE TABLE dir ("</font> +
+<font color="#555555">014 </font> <font color="#0000FF">"did INT,"</font> +
+<font color="#555555">015 </font> <font color="#0000FF">"dname CHAR(100),"</font> +
+<font color="#555555">016 </font> <font color="#0000FF">"fatherdid INT,"</font> +
+<font color="#555555">017 </font> <font color="#0000FF">"entries INT)"</font>
+<font color="#555555">018 </font> );
+<font color="#555555">019 </font> stmt.executeUpdate(<font color="#0000FF">"CREATE INDEX idir1 ON dir ( did )"</font>);
+<font color="#555555">020 </font> stmt.executeUpdate(<font color="#0000FF">"CREATE INDEX idir2 ON dir ( fatherdid )"</font>);
+<font color="#555555">021 </font> <font color="#00AA00">//Anlegen der Tabelle file</font>
+<font color="#555555">022 </font> <font color="#0000AA">try</font> {
+<font color="#555555">023 </font> stmt.executeUpdate(<font color="#0000FF">"DROP TABLE file"</font>);
+<font color="#555555">024 </font> } <font color="#0000AA">catch</font> (SQLException e) {
+<font color="#555555">025 </font> <font color="#00AA00">//Nichts zu tun</font>
+<font color="#555555">026 </font> }
+<font color="#555555">027 </font> stmt.executeUpdate(<font color="#0000FF">"CREATE TABLE file ("</font> +
+<font color="#555555">028 </font> <font color="#0000FF">"fid INT ,"</font> +
+<font color="#555555">029 </font> <font color="#0000FF">"did INT,"</font> +
+<font color="#555555">030 </font> <font color="#0000FF">"fname CHAR(100),"</font> +
+<font color="#555555">031 </font> <font color="#0000FF">"fsize INT,"</font> +
+<font color="#555555">032 </font> <font color="#0000FF">"fdate DATE,"</font> +
+<font color="#555555">033 </font> <font color="#0000FF">"ftime CHAR(5))"</font>
+<font color="#555555">034 </font> );
+<font color="#555555">035 </font> stmt.executeUpdate(<font color="#0000FF">"CREATE INDEX ifile1 ON file ( fid )"</font>);
+<font color="#555555">036 </font>}</pre>
+</font>
+</td>
+</tr>
+</table>
+<i>
+Listing 42.4: Anlegen der DirDB-Tabellen</i></p>
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100%>
+<tr>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top width=1000>
+
+<p>
+Um die Tabellen zu löschen, falls sie bereits vorhanden sind,
+wird zunächst die Anweisung <font color="#000077"><tt>DROP TABLE</tt></font>
+ausgeführt. Sie ist in einem eigenen <a href="index_t.html#ixb100569"><font color=#000080><tt>try</tt></font></a>-<a href="index_c.html#ixb100570"><font color=#000080><tt>catch</tt></font></a>-Block
+gekapselt, denn manche Datenbanken lösen eine Ausnahme aus, falls
+die zu löschenden Tabellen nicht existieren. Diesen »Fehler«
+wollen wir natürlich ignorieren und nicht an den Aufrufer weitergeben.</td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top>
+<table border=0 cellspacing=0 cellpadding=1 width=100% bgcolor="#000077">
+<tr>
+<td><font color="#FFFFFF"> Hinweis </font></td>
+</tr>
+</table>
+</td>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+</tr>
+</table>
+
+<p>
+Nachdem die Tabellen angelegt wurden, können sie mit der Methode
+<font color="#000077"><tt>populate</tt></font> gefüllt werden.
+<font color="#000077"><tt>populate</tt></font> bekommt dazu vom Rahmenprogramm
+den Namen des Startverzeichnisses übergeben, das rekursiv durchlaufen
+werden soll, und ruft <font color="#000077"><tt>addDirectory</tt></font>
+auf, um das erste Verzeichnis mit Hilfe des Kommandos <font color="#000077"><tt>INSERT
+INTO</tt></font> (das ebenfalls an <a href="index_e.html#ixb102250"><font color=#000080><tt>executeUpdate</tt></font></a>
+übergeben wird) in die Tabelle <i>dir</i> einzutragen. Der Code
+sieht etwas unleserlich aus, weil einige Stringliterale einschließlich
+der zugehörigen einfachen Anführungsstriche übergeben
+werden müssen. Sie dienen in SQL-Befehlen als Begrenzungszeichen
+von Zeichenketten.
+
+<p>
+Für das aktuelle Verzeichnis wird dann ein <a href="index_f.html#ixb100973"><font color=#000080><tt>File</tt></font></a>-Objekt
+erzeugt und mit <a name="ixa103103"><a href="index_l.html#ixb101096"><font color=#000080><tt>listFiles</tt></font></a></a>
+(seit dem JDK 1.2 verfügbar) eine Liste der Dateien und Verzeichnisse
+in diesem Verzeichnis erstellt. Jede Datei wird mit einem weiteren
+<font color="#000077"><tt>INSERT INTO</tt></font> in die <i>file</i>-Tabelle
+eingetragen, für jedes Unterverzeichnis ruft <font color="#000077"><tt>addDirectory</tt></font>
+sich selbst rekursiv auf.
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100%>
+<tr>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top width=1000>
+
+<p>
+Am Ende wird mit einem <font color="#000077"><tt>UPDATE</tt></font>-Kommando
+die Anzahl der Einträge im aktuellen Verzeichnis in das Feld
+<i>entries</i> der Tabelle <i>dir</i> eingetragen. Der Grund für
+diese etwas umständliche Vorgehensweise (wir hätten das
+auch gleich beim Anlegen des <i>dir</i>-Satzes erledigen können)
+liegt darin, dass wir auch ein Beispiel für die Anwendung der
+<font color="#000077"><tt>UPDATE</tt></font>-Anweisung geben wollten.</td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top>
+<table border=0 cellspacing=0 cellpadding=1 width=100% bgcolor="#000077">
+<tr>
+<td><font color="#FFFFFF"> Hinweis </font></td>
+</tr>
+</table>
+</td>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+</tr>
+</table>
+<a name="tabellenfuellen"></a>
+
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#DDDDDD">
+<tr>
+<td valign=top>
+<font color="#000055">
+<pre>
+<font color="#555555">001 </font><font color="#00AA00">/**
+<font color="#555555">002 </font> * Durchläuft den Verzeichnisbaum rekursiv und schreibt
+<font color="#555555">003 </font> * Verzeichnis- und Dateinamen in die Datenbank.
+<font color="#555555">004 </font> */</font>
+<font color="#555555">005 </font><font color="#0000AA">public</font> <font color="#0000AA">static</font> <font color="#006699">void</font> populate(String dir)
+<font color="#555555">006 </font><font color="#0000AA">throws</font> Exception
+<font color="#555555">007 </font>{
+<font color="#555555">008 </font> addDirectory(0, <font color="#0000FF">""</font>, dir);
+<font color="#555555">009 </font>}
+<font color="#555555">010 </font>
+<font color="#555555">011 </font><font color="#00AA00">/**
+<font color="#555555">012 </font> * Fügt das angegebene Verzeichnis und alle
+<font color="#555555">013 </font> * Unterverzeichnisse mit allen darin enthaltenen
+<font color="#555555">014 </font> * Dateien zur Datenbank hinzu.
+<font color="#555555">015 </font> */</font>
+<font color="#555555">016 </font><font color="#0000AA">public</font> <font color="#0000AA">static</font> <font color="#006699">void</font> addDirectory(
+<font color="#555555">017 </font> <font color="#006699">int</font> fatherdid, String parent, String name
+<font color="#555555">018 </font>)
+<font color="#555555">019 </font><font color="#0000AA">throws</font> Exception
+<font color="#555555">020 </font>{
+<font color="#555555">021 </font> String dirname = <font color="#0000FF">""</font>;
+<font color="#555555">022 </font> <font color="#0000AA">if</font> (parent.length() > 0) {
+<font color="#555555">023 </font> dirname = parent;
+<font color="#555555">024 </font> <font color="#0000AA">if</font> (!parent.endsWith(FILESEP)) {
+<font color="#555555">025 </font> dirname += FILESEP;
+<font color="#555555">026 </font> }
+<font color="#555555">027 </font> }
+<font color="#555555">028 </font> dirname += name;
+<font color="#555555">029 </font> System.out.println(<font color="#0000FF">"processing "</font> + dirname);
+<font color="#555555">030 </font> File dir = <font color="#0000AA">new</font> File(dirname);
+<font color="#555555">031 </font> <font color="#0000AA">if</font> (!dir.isDirectory()) {
+<font color="#555555">032 </font> <font color="#0000AA">throw</font> <font color="#0000AA">new</font> Exception(<font color="#0000FF">"not a directory: "</font> + dirname);
+<font color="#555555">033 </font> }
+<font color="#555555">034 </font> <font color="#00AA00">//Verzeichnis anlegen</font>
+<font color="#555555">035 </font> <font color="#006699">int</font> did = nextdid++;
+<font color="#555555">036 </font> stmt.executeUpdate(
+<font color="#555555">037 </font> <font color="#0000FF">"INSERT INTO dir VALUES ("</font> +
+<font color="#555555">038 </font> did + <font color="#0000FF">","</font> +
+<font color="#555555">039 </font> <font color="#0000FF">"\'"</font> + name + <font color="#0000FF">"\',"</font> +
+<font color="#555555">040 </font> fatherdid + <font color="#0000FF">","</font> +
+<font color="#555555">041 </font> <font color="#0000FF">"0)"</font>
+<font color="#555555">042 </font> );
+<font color="#555555">043 </font> <font color="#00AA00">//Verzeichniseinträge lesen</font>
+<font color="#555555">044 </font> File[] entries = dir.listFiles();
+<font color="#555555">045 </font> <font color="#00AA00">//Verzeichnis durchlaufen</font>
+<font color="#555555">046 </font> <font color="#0000AA">for</font> (<font color="#006699">int</font> i = 0; i < entries.length; ++i) {
+<font color="#555555">047 </font> <font color="#0000AA">if</font> (entries[i].isDirectory()) {
+<font color="#555555">048 </font> addDirectory(did, dirname, entries[i].getName());
+<font color="#555555">049 </font> } <font color="#0000AA">else</font> {
+<font color="#555555">050 </font> java.util.Date d = <font color="#0000AA">new</font> java.util.Date(
+<font color="#555555">051 </font> entries[i].lastModified()
+<font color="#555555">052 </font> );
+<font color="#555555">053 </font> SimpleDateFormat sdf;
+<font color="#555555">054 </font> <font color="#00AA00">//Datum</font>
+<font color="#555555">055 </font> sdf = <font color="#0000AA">new</font> SimpleDateFormat(<font color="#0000FF">"yyyy-MM-dd"</font>);
+<font color="#555555">056 </font> String date = sdf.format(d);
+<font color="#555555">057 </font> <font color="#00AA00">//Zeit</font>
+<font color="#555555">058 </font> sdf = <font color="#0000AA">new</font> SimpleDateFormat(<font color="#0000FF">"HH:mm"</font>);
+<font color="#555555">059 </font> String time = sdf.format(d);
+<font color="#555555">060 </font> <font color="#00AA00">//Satz anhängen</font>
+<font color="#555555">061 </font> stmt.executeUpdate(
+<font color="#555555">062 </font> <font color="#0000FF">"INSERT INTO file VALUES ("</font> +
+<font color="#555555">063 </font> (nextfid++) + <font color="#0000FF">","</font> +
+<font color="#555555">064 </font> did + <font color="#0000FF">","</font> +
+<font color="#555555">065 </font> <font color="#0000FF">"\'"</font> + entries[i].getName() + <font color="#0000FF">"\',"</font> +
+<font color="#555555">066 </font> entries[i].length() + <font color="#0000FF">","</font> +
+<font color="#555555">067 </font> <font color="#0000FF">"{d \'"</font> + date + <font color="#0000FF">"\'},"</font> +
+<font color="#555555">068 </font> <font color="#0000FF">"\'"</font> + time + <font color="#0000FF">"\')"</font>
+<font color="#555555">069 </font> );
+<font color="#555555">070 </font> System.out.println(<font color="#0000FF">" "</font> + entries[i].getName());
+<font color="#555555">071 </font> }
+<font color="#555555">072 </font> }
+<font color="#555555">073 </font> <font color="#00AA00">//Anzahl der Einträge aktualisieren</font>
+<font color="#555555">074 </font> stmt.executeUpdate(
+<font color="#555555">075 </font> <font color="#0000FF">"UPDATE dir SET entries = "</font> + entries.length +
+<font color="#555555">076 </font> <font color="#0000FF">" WHERE did = "</font> + did
+<font color="#555555">077 </font> );
+<font color="#555555">078 </font>}</pre>
+</font>
+</td>
+</tr>
+</table>
+<i>
+Listing 42.5: Füllen der DirDB-Tabellen</i></p>
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100%>
+<tr>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top width=1000>
+
+<p>
+Hier tauchen die beiden im Rahmenprogramm definierten statischen Variablen
+<font color="#000077"><tt>nextdid</tt></font> und <font color="#000077"><tt>nextfid</tt></font>
+wieder auf. Sie liefern die Primärschlüssel für Datei-
+und Verzeichnissätze und werden nach jedem eingefügten Satz
+automatisch um eins erhöht. Daß dieses Verfahren nicht
+mehrbenutzerfähig ist, leuchtet ein, denn die Zähler werden
+<i>lokal zur laufenden Applikation</i> erhöht. Eine bessere Lösung
+bieten Primärschlüsselfelder, die beim Einfügen <i>von
+der Datenbank</i> einen automatisch hochgezählten eindeutigen
+Wert erhalten. Dafür sieht JDBC allerdings kein standardisiertes
+Verfahren vor, meist kann ein solches Feld in der <a name="ixa103104"><a href="index_i.html#ixb102267"><font color=#000080><tt>INSERT INTO</tt></font></a></a>-Anweisung
+einfach ausgelassen werden. Alternativ könnten Schlüsselwerte
+vor dem Einfügen aus einer zentralen Key-Tabelle geholt und transaktionssicher
+hochgezählt werden.</td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top>
+<table border=0 cellspacing=0 cellpadding=1 width=100% bgcolor="#000077">
+<tr>
+<td><font color="#FFFFFF"> Hinweis </font></td>
+</tr>
+</table>
+</td>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+</tr>
+</table>
+
+
+<!-- Section -->
+<a name="zaehlenverzdateien"></a>
+<h3>42.3.5 Zählen der Verzeichnisse und Dateien </h3>
+
+<p>
+Das <font color="#000077"><tt>COUNT</tt></font>-Kommando soll die
+Anzahl der Verzeichnisse und Dateien zählen, die mit dem <font color="#000077"><tt>POPULATE</tt></font>-Kommando
+in die Datei eingefügt wurden. Wir verwenden dazu ein einfaches
+<font color="#000077"><tt>SELECT</tt></font>-Kommando, das mit der
+<font color="#000077"><tt>COUNT(*)</tt></font>-Option die Anzahl der
+Sätze in einer Tabelle zählt:
+<a name="listingid042006"></a>
+
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#DDDDDD">
+<tr>
+<td valign=top>
+<font color="#000055">
+<pre>
+<font color="#555555">001 </font><font color="#00AA00">/**
+<font color="#555555">002 </font> * Gibt die Anzahl der Dateien und Verzeichnisse aus.
+<font color="#555555">003 </font> */</font>
+<font color="#555555">004 </font><font color="#0000AA">public</font> <font color="#0000AA">static</font> <font color="#006699">void</font> countRecords()
+<font color="#555555">005 </font><font color="#0000AA">throws</font> SQLException
+<font color="#555555">006 </font>{
+<font color="#555555">007 </font> ResultSet rs = stmt.executeQuery(
+<font color="#555555">008 </font> <font color="#0000FF">"SELECT count(*) FROM dir"</font>
+<font color="#555555">009 </font> );
+<font color="#555555">010 </font> <font color="#0000AA">if</font> (!rs.next()) {
+<font color="#555555">011 </font> <font color="#0000AA">throw</font> <font color="#0000AA">new</font> SQLException(<font color="#0000FF">"SELECT COUNT(*): no result"</font>);
+<font color="#555555">012 </font> }
+<font color="#555555">013 </font> System.out.println(<font color="#0000FF">"Directories: "</font> + rs.getInt(1));
+<font color="#555555">014 </font> rs = stmt.executeQuery(<font color="#0000FF">"SELECT count(*) FROM file"</font>);
+<font color="#555555">015 </font> <font color="#0000AA">if</font> (!rs.next()) {
+<font color="#555555">016 </font> <font color="#0000AA">throw</font> <font color="#0000AA">new</font> SQLException(<font color="#0000FF">"SELECT COUNT(*): no result"</font>);
+<font color="#555555">017 </font> }
+<font color="#555555">018 </font> System.out.println(<font color="#0000FF">"Files: "</font> + rs.getInt(1));
+<font color="#555555">019 </font> rs.close();
+<font color="#555555">020 </font>}</pre>
+</font>
+</td>
+</tr>
+</table>
+<i>
+Listing 42.6: Anzahl der Sätze in der DirDB-Datenbank</i></p>
+
+<p>
+Die <font color="#000077"><tt>SELECT</tt></font>-Befehle werden mit
+der Methode <a href="index_e.html#ixb102249"><font color=#000080><tt>executeQuery</tt></font></a>
+an das <a href="index_s.html#ixb102247"><font color=#000080><tt>Statement</tt></font></a>-Objekt
+übergeben, denn wir erwarten nicht nur eine einfache Ganzzahl
+als Rückgabewert, sondern eine komplette Ergebnismenge. Die Besonderheit
+liegt in diesem Fall darin, dass wegen der Spaltenangabe <font color="#000077"><tt>COUNT(*)</tt></font>
+lediglich ein einziger Satz zurückgegeben wird, der auch nur
+ein einziges Feld enthält. Auf dieses können wir am einfachsten
+über seinen numerischen Index 1 zugreifen und es durch Aufruf
+von <a href="index_g.html#ixb102253"><font color=#000080><tt>getInt</tt></font></a>
+gleich in ein <a href="index_i.html#ixb100244"><font color=#000080><tt>int</tt></font></a>
+umwandeln lassen. Das Ergebnis geben wir auf dem Bildschirm aus und
+wiederholen anschließend dieselbe Prozedur für die Tabelle
+<i>file</i>.
+
+<!-- Section -->
+
+<a name="sectlevel3id042003006"></a>
+<h3>42.3.6 Suchen von Dateien und Verzeichnissen </h3>
+
+<p>
+Um eine bestimmte Datei oder Tabelle in unserer Datenbank zu suchen,
+verwenden wir ebenfalls ein <font color="#000077"><tt>SELECT</tt></font>-Statement.
+Im Gegensatz zu vorher lassen wir uns nun mit der Spaltenangabe »*«
+<i>alle</i> Felder der Tabelle geben. Zudem hängen wir an die
+Abfrageanweisung eine <font color="#000077"><tt>WHERE</tt></font>-Klausel
+an, um eine Suchbedingung formulieren zu können. Mit Hilfe des
+<font color="#000077"><tt>LIKE</tt></font>-Operators führen wir
+eine Mustersuche durch, bei der die beiden SQL-Wildcards »%«
+(eine beliebige Anzahl Zeichen) und »_« (ein einzelnes beliebiges
+Zeichen) verwendet werden können. Zusätzlich bekommt InstantDB
+die (nicht SQL-92-konforme) Option <font color="#000077"><tt>IGNORE
+CASE</tt></font> angehängt, um bei der Suche nicht zwischen Groß-
+und Kleinschreibung zu unterscheiden (ist bei Access 7.0 nicht nötig).
+
+<p>
+Die von <a href="index_e.html#ixb102249"><font color=#000080><tt>executeQuery</tt></font></a>
+zurückgegebene Ergebnismenge wird mit <a href="index_n.html#ixb100509"><font color=#000080><tt>next</tt></font></a>
+Satz für Satz durchlaufen und auf dem Bildschirm ausgegeben.
+Mit Hilfe der Methode <font color="#000077"><tt>getDirPath</tt></font>
+wird zuvor der zugehörige Verzeichnisname rekonstruiert und vor
+dem Dateinamen ausgegeben. Dazu wird in einer Schleife zur angegebenen
+<font color="#000077"><tt>did</tt></font> (Verzeichnisschlüssel)
+so lange das zugehörige Verzeichnis gesucht, bis dessen <font color="#000077"><tt>fatherdid</tt></font>
+0 ist, also das Startverzeichnis erreicht ist. Rückwärts
+zusammengebaut und mit Trennzeichen versehen, ergibt diese Namenskette
+den kompletten Verzeichnisnamen.
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100%>
+<tr>
+<td width=1 align=left valign=top bgcolor="#CC0000"><img src="trp1_1.gif"></td>
+<td><img src="trp1_1.gif" width=1></td>
+<td width=1 align=left valign=top bgcolor="#CC0000"><img src="trp1_1.gif"></td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top width=1000>
+
+<p>
+Der in dieser Methode verwendete <a href="index_r.html#ixb102252"><font color=#000080><tt>ResultSet</tt></font></a>
+wurde mit dem zweiten <a href="index_s.html#ixb102247"><font color=#000080><tt>Statement</tt></font></a>-Objekt
+<font color="#000077"><tt>stmt1</tt></font> erzeugt. Hätten wir
+dafür die zu diesem Zeitpunkt noch geöffnete Variable <font color="#000077"><tt>stmt</tt></font>
+verwendet, wäre das Verhalten des Programms undefiniert gewesen,
+weil die bestehende Ergebnismenge durch das Erzeugen einer neuen Ergebnismenge
+auf demselben <a href="index_s.html#ixb102247"><font color=#000080><tt>Statement</tt></font></a>-Objekt
+ungültig geworden wäre.</td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top>
+<table border=0 cellspacing=0 cellpadding=1 width=100% bgcolor="#CC0000">
+<tr>
+<td><font color="#FFFFFF"> Warnung </font></td>
+</tr>
+</table>
+</td>
+<td width=1 align=left valign=top bgcolor="#CC0000"><img src="trp1_1.gif"></td>
+</tr>
+</table>
+<a name="listingid042007"></a>
+
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#DDDDDD">
+<tr>
+<td valign=top>
+<font color="#000055">
+<pre>
+<font color="#555555">001 </font><font color="#00AA00">/**
+<font color="#555555">002 </font> * Gibt eine Liste aller Files auf dem Bildschirm aus,
+<font color="#555555">003 </font> * die zu dem angegebenen Dateinamen passen. Darin dürfen
+<font color="#555555">004 </font> * die üblichen SQL-Wildcards % und _ enthalten sein.
+<font color="#555555">005 </font> */</font>
+<font color="#555555">006 </font><font color="#0000AA">public</font> <font color="#0000AA">static</font> <font color="#006699">void</font> findFile(String name)
+<font color="#555555">007 </font><font color="#0000AA">throws</font> SQLException
+<font color="#555555">008 </font>{
+<font color="#555555">009 </font> String query = <font color="#0000FF">"SELECT * FROM file "</font> +
+<font color="#555555">010 </font> <font color="#0000FF">"WHERE fname LIKE \'"</font> + name + <font color="#0000FF">"\'"</font>;
+<font color="#555555">011 </font> <font color="#0000AA">if</font> (db == INSTANT185) {
+<font color="#555555">012 </font> query += <font color="#0000FF">" IGNORE CASE"</font>;
+<font color="#555555">013 </font> }
+<font color="#555555">014 </font> ResultSet rs = stmt.executeQuery(query);
+<font color="#555555">015 </font> <font color="#0000AA">while</font> (rs.next()) {
+<font color="#555555">016 </font> String path = getDirPath(rs.getInt(<font color="#0000FF">"did"</font>));
+<font color="#555555">017 </font> System.out.println(
+<font color="#555555">018 </font> path + FILESEP +
+<font color="#555555">019 </font> rs.getString(<font color="#0000FF">"fname"</font>).trim()
+<font color="#555555">020 </font> );
+<font color="#555555">021 </font> }
+<font color="#555555">022 </font> rs.close();
+<font color="#555555">023 </font>}
+<font color="#555555">024 </font>
+<font color="#555555">025 </font><font color="#00AA00">/**
+<font color="#555555">026 </font> * Liefert den Pfadnamen zu dem Verzeichnis mit dem
+<font color="#555555">027 </font> * angegebenen Schlüssel.
+<font color="#555555">028 </font> */</font>
+<font color="#555555">029 </font><font color="#0000AA">public</font> <font color="#0000AA">static</font> String getDirPath(<font color="#006699">int</font> did)
+<font color="#555555">030 </font><font color="#0000AA">throws</font> SQLException
+<font color="#555555">031 </font>{
+<font color="#555555">032 </font> String ret = <font color="#0000FF">""</font>;
+<font color="#555555">033 </font> <font color="#0000AA">while</font> (<font color="#006699">true</font>) {
+<font color="#555555">034 </font> ResultSet rs = stmt1.executeQuery(
+<font color="#555555">035 </font> <font color="#0000FF">"SELECT * FROM dir WHERE did = "</font> + did
+<font color="#555555">036 </font> );
+<font color="#555555">037 </font> <font color="#0000AA">if</font> (!rs.next()) {
+<font color="#555555">038 </font> <font color="#0000AA">throw</font> <font color="#0000AA">new</font> SQLException(
+<font color="#555555">039 </font> <font color="#0000FF">"no dir record found with did = "</font> + did
+<font color="#555555">040 </font> );
+<font color="#555555">041 </font> }
+<font color="#555555">042 </font> ret = rs.getString(<font color="#0000FF">"dname"</font>).trim() +
+<font color="#555555">043 </font> (ret.length() > 0 ? FILESEP + ret : <font color="#0000FF">""</font>);
+<font color="#555555">044 </font> <font color="#0000AA">if</font> ((did = rs.getInt(<font color="#0000FF">"fatherdid"</font>)) == 0) {
+<font color="#555555">045 </font> <font color="#0000AA">break</font>;
+<font color="#555555">046 </font> }
+<font color="#555555">047 </font> }
+<font color="#555555">048 </font> <font color="#0000AA">return</font> ret;
+<font color="#555555">049 </font>}</pre>
+</font>
+</td>
+</tr>
+</table>
+<i>
+Listing 42.7: Suchen nach Dateien in der DirDB-Datenbank</i></p>
+
+<p>
+Das DirDB-Programm bietet mit dem Kommando <font color="#000077"><tt>FINDDIR</tt></font>
+auch die Möglichkeit, nach Verzeichnisnamen zu suchen. Die Implementierung
+dieser Funktion ähnelt der vorigen und wird durch die Methode
+<font color="#000077"><tt>findDir</tt></font> realisiert:
+<a name="listingid042008"></a>
+
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#DDDDDD">
+<tr>
+<td valign=top>
+<font color="#000055">
+<pre>
+<font color="#555555">001 </font><font color="#00AA00">/**
+<font color="#555555">002 </font> * Gibt eine Liste aller Verzeichnisse auf dem Bildschirm
+<font color="#555555">003 </font> * aus, die zu dem angegebenen Verzeichnisnamen passen.
+<font color="#555555">004 </font> * Darin dürfen die üblichen SQL-Wildcards % und _
+<font color="#555555">005 </font> * enthalten sein.
+<font color="#555555">006 </font> */</font>
+<font color="#555555">007 </font><font color="#0000AA">public</font> <font color="#0000AA">static</font> <font color="#006699">void</font> findDir(String name)
+<font color="#555555">008 </font><font color="#0000AA">throws</font> SQLException
+<font color="#555555">009 </font>{
+<font color="#555555">010 </font> String query = <font color="#0000FF">"SELECT * FROM dir "</font> +
+<font color="#555555">011 </font> <font color="#0000FF">"WHERE dname LIKE \'"</font> + name + <font color="#0000FF">"\'"</font>;
+<font color="#555555">012 </font> <font color="#0000AA">if</font> (db == INSTANT185) {
+<font color="#555555">013 </font> query += <font color="#0000FF">" IGNORE CASE"</font>;
+<font color="#555555">014 </font> }
+<font color="#555555">015 </font> ResultSet rs = stmt.executeQuery(query);
+<font color="#555555">016 </font> <font color="#0000AA">while</font> (rs.next()) {
+<font color="#555555">017 </font> System.out.println(
+<font color="#555555">018 </font> getDirPath(rs.getInt(<font color="#0000FF">"did"</font>)) +
+<font color="#555555">019 </font> <font color="#0000FF">" ("</font> + rs.getInt(<font color="#0000FF">"entries"</font>) + <font color="#0000FF">" entries)"</font>
+<font color="#555555">020 </font> );
+<font color="#555555">021 </font> }
+<font color="#555555">022 </font> rs.close();
+<font color="#555555">023 </font>}</pre>
+</font>
+</td>
+</tr>
+</table>
+<i>
+Listing 42.8: Suchen nach Verzeichnissen in der DirDB-Datenbank</i></p>
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100%>
+<tr>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top width=1000>
+
+<p>
+Wird das DirDB-Programm von der Kommandozeile aufgerufen, kann es
+unter Umständen schwierig sein, die Wildcards »%« oder
+»_« einzugeben, weil sie vom Betriebssystem oder der Shell
+als Sonderzeichen angesehen werden. Durch Voranstellen des passenden
+Escape-Zeichens (das könnte beispielsweise der Backslash sein)
+kann die Sonderbedeutung aufgehoben werden. In der DOS-Box von Windows
+95 oder NT kann die Sonderbedeutung des »%« nur aufgehoben
+werden, indem das Zeichen »%« doppelt geschrieben wird.
+Soll beispielsweise nach allen Dateien mit der Erweiterung <font color="#660099">.java</font>
+gesucht werden, so ist <font color="#000077"><tt>DirDb</tt></font>
+unter Windows wie folgt aufzurufen:
+<font color="#000077">
+<pre>
+java DirDB I findfile %%.java
+</pre>
+</font>
+
+<p>
+Weiterhin ist zu beachten, dass die Interpretation der Wildcards von
+den unterschiedlichen Datenbanken leider nicht einheitlich gehandhabt
+wird. Während das obige Kommando unter InstantDB korrekt funktioniert,
+ist bei der Access-Datenbank die Ergebnismenge leer. Der Grund kann
+- je nach verwendeter Version - darin liegen, dass entweder der Stern
+»*« anstelle des »%« als Wildcard erwartet wird
+oder dass die <i>Leerzeichen am Ende des Feldes</i> als signifikant
+angesehen werden und daher auch <i>hinter</i> dem Suchbegriff ein
+Wildcard-Zeichen angegeben werden muss:
+<font color="#000077">
+<pre>
+java DirDB A findfile %%.java%%
+</pre>
+</font>
+</td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top>
+<table border=0 cellspacing=0 cellpadding=1 width=100% bgcolor="#000077">
+<tr>
+<td><font color="#FFFFFF"> Hinweis </font></td>
+</tr>
+</table>
+</td>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+</tr>
+</table>
+
+
+<!-- Section -->
+<a name="sectlevel3id042003007"></a>
+<h3>42.3.7 Die zehn größten Dateien </h3>
+
+<p>
+Eine ähnliche <font color="#000077"><tt>SELECT</tt></font>-Anweisung
+begegnet uns, wenn wir uns die Aufgabe stellen, die <i>howmany</i>
+größten Dateien unserer Datenbank anzuzeigen. Hierzu fügen
+wir eine <font color="#000077"><tt>ORDER BY</tt></font>-Klausel an
+und sortieren die Abfrage absteigend nach der Spalte <i>fsize</i>.
+Von der Ergebnismenge geben wir dann die ersten <i>howmany</i> Elemente
+aus:
+<a name="listingid042009"></a>
+
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#DDDDDD">
+<tr>
+<td valign=top>
+<font color="#000055">
+<pre>
+<font color="#555555">001 </font><font color="#00AA00">/**
+<font color="#555555">002 </font> * Gibt die howmany größten Dateien aus.
+<font color="#555555">003 </font> */</font>
+<font color="#555555">004 </font><font color="#0000AA">public</font> <font color="#0000AA">static</font> <font color="#006699">void</font> biggestFiles(<font color="#006699">int</font> howmany)
+<font color="#555555">005 </font><font color="#0000AA">throws</font> SQLException
+<font color="#555555">006 </font>{
+<font color="#555555">007 </font> ResultSet rs = stmt.executeQuery(
+<font color="#555555">008 </font> <font color="#0000FF">"SELECT * FROM file ORDER BY fsize DESC"</font>
+<font color="#555555">009 </font> );
+<font color="#555555">010 </font> <font color="#0000AA">for</font> (<font color="#006699">int</font> i = 0; i < howmany; ++i) {
+<font color="#555555">011 </font> <font color="#0000AA">if</font> (rs.next()) {
+<font color="#555555">012 </font> System.out.print(
+<font color="#555555">013 </font> getDirPath(rs.getInt(<font color="#0000FF">"did"</font>)) +
+<font color="#555555">014 </font> FILESEP + rs.getString(<font color="#0000FF">"fname"</font>).trim()
+<font color="#555555">015 </font> );
+<font color="#555555">016 </font> System.out.println(
+<font color="#555555">017 </font> Str.getFormatted(<font color="#0000FF">"%10d"</font>, rs.getInt(<font color="#0000FF">"fsize"</font>))
+<font color="#555555">018 </font> );
+<font color="#555555">019 </font> }
+<font color="#555555">020 </font> }
+<font color="#555555">021 </font> rs.close();
+<font color="#555555">022 </font>}</pre>
+</font>
+</td>
+</tr>
+</table>
+<i>
+Listing 42.9: Sortieren der Ergebnismenge</i></p>
+
+
+<!-- Section -->
+<a name="sectlevel3id042003008"></a>
+<h3>42.3.8 Speicherverschwendung durch Clustering </h3>
+
+<p>
+Bevor wir uns weiterführenden Themen zuwenden, wollen wir uns
+eine letzte Anwendung unserer Beispieldatenbank ansehen. Viele Dateisysteme
+(allen voran das alte FAT-Dateisystem unter MS-DOS und Windows) speichern
+die Dateien in verketteten Zuordnungseinheiten fester Größe,
+den <a name="ixa103105"><i>Clustern</i></a>. Ist die Clustergröße
+beispielsweise 4096 Byte, so belegt eine Datei auch dann 4 kByte Speicher,
+wenn sie nur ein Byte groß ist. Immer, wenn die Größe
+einer Datei nicht ein genaues Vielfaches der Clustergröße
+ist, bleibt der letzte Cluster unvollständig belegt und wertvoller
+Plattenspeicher bleibt ungenutzt. Ist die Clustergröße
+hoch, wird vor allem dann viel Platz verschwendet, wenn das Dateisystem
+sehr viele kleine Dateien enthält. Die folgende Funktion <font color="#000077"><tt>clustering</tt></font>
+berechnet zu einer gegebenen Clustergröße die Summe der
+Dateilängen und stellt sie dem tatsächlichen Platzbedarf
+aufgrund der geclusterten Speicherung gegenüber:
+<a name="listingid042010"></a>
+
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#DDDDDD">
+<tr>
+<td valign=top>
+<font color="#000055">
+<pre>
+<font color="#555555">001 </font><font color="#00AA00">/**
+<font color="#555555">002 </font> * Summiert einerseits die tatsächliche Größe aller
+<font color="#555555">003 </font> * Dateien und andererseits die Größe, die sie durch
+<font color="#555555">004 </font> * das Clustering mit der angegebenen Clustergröße
+<font color="#555555">005 </font> * belegen. Zusätzlich wird der durch das Clustering
+<font color="#555555">006 </font> * "verschwendete" Speicherplatz ausgegeben.
+<font color="#555555">007 </font> */</font>
+<font color="#555555">008 </font><font color="#0000AA">public</font> <font color="#0000AA">static</font> <font color="#006699">void</font> clustering(<font color="#006699">int</font> clustersize)
+<font color="#555555">009 </font><font color="#0000AA">throws</font> SQLException
+<font color="#555555">010 </font>{
+<font color="#555555">011 </font> <font color="#006699">int</font> truesize = 0;
+<font color="#555555">012 </font> <font color="#006699">int</font> clusteredsize = 0;
+<font color="#555555">013 </font> <font color="#006699">double</font> wasted;
+<font color="#555555">014 </font> ResultSet rs = stmt.executeQuery(
+<font color="#555555">015 </font> <font color="#0000FF">"SELECT * FROM file"</font>
+<font color="#555555">016 </font> );
+<font color="#555555">017 </font> <font color="#0000AA">while</font> (rs.next()) {
+<font color="#555555">018 </font> <font color="#006699">int</font> fsize = rs.getInt(<font color="#0000FF">"fsize"</font>);
+<font color="#555555">019 </font> truesize += fsize;
+<font color="#555555">020 </font> <font color="#0000AA">if</font> (fsize % clustersize == 0) {
+<font color="#555555">021 </font> clusteredsize += fsize;
+<font color="#555555">022 </font> } <font color="#0000AA">else</font> {
+<font color="#555555">023 </font> clusteredsize += ((fsize / clustersize) + 1)*clustersize;
+<font color="#555555">024 </font> }
+<font color="#555555">025 </font> }
+<font color="#555555">026 </font> System.out.println(<font color="#0000FF">"true size = "</font> + truesize);
+<font color="#555555">027 </font> System.out.println(<font color="#0000FF">"clustered size = "</font> + clusteredsize);
+<font color="#555555">028 </font> wasted = 100 * (1 - ((<font color="#006699">double</font>)truesize / clusteredsize));
+<font color="#555555">029 </font> System.out.println(<font color="#0000FF">"wasted space = "</font> + wasted + <font color="#0000FF">" %"</font>);
+<font color="#555555">030 </font>}</pre>
+</font>
+</td>
+</tr>
+</table>
+<i>
+Listing 42.10: Cluster-Berechnung mit der DirDB-Datenbank</i></p>
+
+<p>
+Um beispielsweise den Einfluss der geclusterten Darstellung bei einer
+Clustergröße von 8192 zu ermitteln, kann das Programm wie
+folgt aufgerufen werden:
+<font color="#000077">
+<pre>
+java DirDB I clustering 8192
+</pre>
+</font>
+
+<p>
+Die Ausgabe des Programms könnte dann beispielsweise so aussehen:
+<font color="#333300">
+<pre>
+InstantDB - Version 1.85
+Copyright (c) 1997-1998 Instant Computer Solutions Ltd.
+
+Connection URL: jdbc:idb:dirdb.prp
+Driver Name: InstantDB JDBC Driver
+Driver Version: Version 1.85
+
+true size = 94475195
+clustered size = 112861184
+wasted space = 16.290799323884464 %
+</pre>
+</font>
+<hr>
+<table border=0 cellpadding=0 cellspacing=1 width="100%">
+<tr bgcolor="#EEFFCC">
+<td width="7%" align=center bgcolor="#DDCC99"><a href="cover.html"> Titel </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100003.html"> Inhalt </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="search.html"> Suchen </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="index.html"> Index </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/index.html" onClick="this.href=getDocIndex()"> DOC </a>
+<td align="right">Handbuch der Java-Programmierung, 5. Auflage, Addison
+Wesley, Version 5.0.1
+<tr bgcolor="#EEFFCC">
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100265.html"> << </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100267.html"> < </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100269.html"> > </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100271.html"> >> </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/api/index.html" onClick="this.href=getApiIndex()"> API </a>
+<td align="right">© 1998, 2007 Guido Krüger & Thomas
+Stark, <a href="http://www.javabuch.de">http://www.javabuch.de</a>
+</table>
+<a name="endofbody"></a>
+</body>
+</html>
|
