From 33613a85afc4b1481367fbe92a17ee59c240250b Mon Sep 17 00:00:00 2001 From: Sven Eisenhauer Date: Fri, 10 Nov 2023 15:11:48 +0100 Subject: add new repo --- .../hjp5/html/k100140.html | 517 +++++++++++++++++++++ 1 file changed, 517 insertions(+) create mode 100644 Master/Reference Architectures and Patterns/hjp5/html/k100140.html (limited to 'Master/Reference Architectures and Patterns/hjp5/html/k100140.html') diff --git a/Master/Reference Architectures and Patterns/hjp5/html/k100140.html b/Master/Reference Architectures and Patterns/hjp5/html/k100140.html new file mode 100644 index 0000000..279da92 --- /dev/null +++ b/Master/Reference Architectures and Patterns/hjp5/html/k100140.html @@ -0,0 +1,517 @@ + + + +Handbuch der Java-Programmierung, 5. Auflage + + + + + + + + + +
 Titel  + Inhalt  + Suchen  + Index  + DOC  +Handbuch der Java-Programmierung, 5. Auflage +
 <<  +  <   +  >   + >>  + API  +Kapitel 21 - Datei- und Verzeichnis-Handling +
+
+ + + + +

21.4 Zugriff auf Verzeichniseinträge +

+
+ +
+ + + + +

21.4.1 Lesen von Verzeichniseinträgen

+ +

+Wurde ein File-Objekt +für ein Verzeichnis konstruiert, so stehen weitere Methoden zur +Verfügung, um auf die zusätzlichen Funktionen eines Verzeichnisses +zuzugreifen. Mit Hilfe der Methode list +ist es beispielsweise möglich, den Inhalt des Verzeichnisses +auszulesen: +

+ + + + + +
+ +
+public String[] list()
+
+
+
+java.io.File
+ +

+list +liefert ein Array von Strings, das für jeden gefundenen Verzeichniseintrag +ein Element enthält. Die Liste enthält die Namen aller Dateien +und Unterverzeichnisse mit Ausnahme von . +und ... list +gibt es noch in einer zweiten Variante, bei der die Auswahl der Verzeichniseinträge +eingeschränkt werden kann. Dabei muss ein Objekt übergeben +werden, das das Interface FilenameFilter +implementiert. Dieses besitzt eine Methode accept, +die für jede gefundene Datei aufgerufen wird und entscheidet, +ob sie in die Liste aufgenommen werden soll oder nicht. + +

+Zusätzlich gibt es die statische Methode listRoots, +mit der eine Liste aller »Wurzeln« der verfügbaren +Dateisysteme beschafft werden kann. Unter UNIX gibt es lediglich die +Wurzel »/«, unter Windows dagegen eine für jeden Laufwerksbuchstaben. + +

+Eine häufig benötigte Funktion besteht darin, ein Verzeichnis +samt seiner Unterverzeichnisse rekursiv zu durchlaufen und bei jedem +gefundenen Eintrag eine bestimmte Aufgabe zu erledigen. Wir wollen +zeigen, wie mit Hilfe des Visitor-Patterns (siehe Abschnitt 10.4.8) +eine universell verwendbare Lösung geschaffen werden kann. Zunächst +definieren wir dazu ein Interface DirectoryVisitor: + + +

+ + + + + +
+ +
+001 /* DirectoryVisitor.java */
+002 
+003 import java.io.*;
+004 
+005 public interface DirectoryVisitor
+006 {
+007   public void enterDirectory(File dir);
+008   public void leaveDirectory(File dir);
+009   public void visitFile(File file);
+010 }
+
+
+DirectoryVisitor.java
+ +Listing 21.2: Das Interface DirectoryVisitor

+ +

+Beim Betreten eines Verzeichnisses wird enterDirectory +aufgerufen, beim Verlassen leaveDirectory. +Zu jedem darin enthaltenen Dateieintrag wird visitFile +aufgerufen. Um es der konkreten Visitor-Implementierung so einfach +wie möglich zu machen, werden sowohl Verzeichnisse als auch Dateien +als fertige File-Objekte +übergeben. + +

+Ein konkreter Visitor, der eine Verzeichnisstruktur mit den darin +enthaltenen Dateien und Unterverzeichnissen korrekt eingerückt +auf dem Bildschirm ausgibt, entsteht durch Implementieren von DirectoryVisitor +wie folgt: + + +

+ + + + + +
+ +
+001 /* DirectoryPrintVisitor.java */
+002 
+003 import java.io.*;
+004 
+005 public class DirectoryPrintVisitor
+006 implements DirectoryVisitor
+007 {
+008   String indent = "";
+009 
+010   public void enterDirectory(File dir)
+011   {
+012     System.out.println(indent + "[" + dir.getName() + "]");
+013     indent += "  ";
+014   }
+015 
+016   public void leaveDirectory(File dir)
+017   {
+018     indent = indent.substring(2);
+019   }
+020 
+021   public void visitFile(File file)
+022   {
+023     System.out.println(indent + file.getName());
+024   }
+025 }
+
+
+DirectoryPrintVisitor.java
+ +Listing 21.3: Ein DirectoryVisitor zum Ausdrucken eines Verzeichnisses

+ +

+In ähnlicher Weise kann ein DirectoryVisitor +geschrieben werden, der die Anzahl der Dateien und Verzeichnisse zählt +und die kumulierte Größe der darin enthaltenen Dateien +ermittelt: + + +

+ + + + + +
+ +
+001 /* DirectorySizeVisitor.java */
+002 
+003 import java.io.*;
+004 
+005 public class DirectorySizeVisitor
+006 implements DirectoryVisitor
+007 {
+008   int  files = 0;
+009   int  dirs  = 0;
+010   long size  = 0;
+011 
+012   public void enterDirectory(File dir)
+013   {
+014     ++dirs;
+015   }
+016 
+017   public void leaveDirectory(File dir)
+018   {
+019   }
+020 
+021   public void visitFile(File file)
+022   {
+023     ++files;
+024     size += file.length();
+025   }
+026 
+027   public int getDirs()
+028   {
+029     return dirs;
+030   }
+031 
+032   public int getFiles()
+033   {
+034     return files;
+035   }
+036 
+037   public long getSize()
+038   {
+039     return size;
+040   }
+041 }
+
+
+DirectorySizeVisitor.java
+ +Listing 21.4: Die Klasse DirectorySizeVisitor

+ +

+Nun fehlen nur noch die generische Methode für den rekursiven +Verzeichnisdurchlauf und ein Beispielprogramm, das die Anwendung der +Klassen im Zusammenspiel zeigt: + + +

+ + + + + +
+ +
+001 /* Listing2105.java */
+002 
+003 import java.io.*;
+004 
+005 public class Listing2105
+006 {
+007   static void traverse(File dir, DirectoryVisitor visitor)
+008   {
+009     if (!dir.isDirectory()) {
+010       throw new IllegalArgumentException(
+011         "not a directory: " + dir.getName()
+012       );
+013     }
+014     visitor.enterDirectory(dir);
+015     File[] entries = dir.listFiles(
+016       new FileFilter()
+017       {
+018         public boolean accept(File pathname)
+019         {
+020           return true;
+021         }
+022       }
+023     );
+024     for (int i = 0; i < entries.length; ++i) {
+025       if (entries[i].isDirectory()) {
+026         traverse(entries[i], visitor);
+027       } else {
+028         visitor.visitFile(entries[i]);
+029       }
+030     }
+031     visitor.leaveDirectory(dir);
+032   }
+033 
+034   public static void main(String[] args)
+035   {
+036     File file = new File(args[0]);
+037     //Bildschirmausgabe der Struktur
+038     traverse(file, new DirectoryPrintVisitor());
+039     //Größen ermitteln
+040     DirectorySizeVisitor visitor = new DirectorySizeVisitor();
+041     traverse(file, visitor);
+042     System.out.println("directories: " + visitor.getDirs());
+043     System.out.println("files: "       + visitor.getFiles());
+044     System.out.println("size: "        + visitor.getSize());
+045   }
+046 }
+
+
+Listing2105.java
+ +Listing 21.5: Rekursiver Durchlauf von Verzeichnissen

+ +

+Die eigentliche Arbeit wird von traverse +erledigt. Sie stellt zunächst sicher, dass das übergebene +File-Objekt +auch tatsächlich ein Verzeichnis darstellt, und nicht etwa eine +Datei. Ist das der Fall, wird auf dem übergebenen Visitor enterDirectory +aufgerufen und mit listFiles +eine Liste aller im Verzeichnis enthaltenen Dateien und Unterverzeichnisse +beschafft. Zu jedem Unterverzeichnis erfolgt ein rekursiver Aufruf +von traverse, zu jeder Datei +wird visitFile aufgerufen. Nachdem +alle Einträge abgearbeitet sind, wird das dem Visitor durch Aufruf +von leaveDirectory mitgeteilt. +

+ + + + + + + + + + + +
+ +

+Die Methode listFiles +gibt es seit der Version 1.2 im JDK. Muß für eine ältere +JDK-Version entwickelt werden, kann alternativ list +verwendet werden. Diese gibt allerdings kein File-, +sondern ein String-Array +zurück.

+ + + + +
 JDK1.1-6.0 
+
+ + + + +

21.4.2 Ändern von Verzeichniseinträgen

+ +

+Neben dem Zugriff auf die Verzeichniseinträge gibt es in der +Klasse File +auch Methoden, um Dateien oder Verzeichnisse zu löschen oder +umzubenennen und um Verzeichnisse neu anzulegen: +

+ + + + + +
+ +
+public boolean mkdir()
+public boolean mkdirs()
+
+public boolean renameTo(File dest)
+
+public boolean delete()
+
+
+
+java.io.File
+ +

+Die Methode delete +löscht die durch das File-Objekt +bezeichnete Datei. Mit renameTo +wird das File-Objekt +in das als Parameter übergebene Objekt umbenannt. Durch Aufruf +von mkdir +wird das durch das File-Objekt +spezifizierte Verzeichnis angelegt. Mit mkdirs +werden sogar alle Vaterverzeichnisse automatisch angelegt, wenn sie +noch nicht existieren. Alle Methoden geben true +zurück, wenn sie ihre Aufgabe erfolgreich ausführen konnten. +Andernfalls geben sie false +zurück. + +

+Das folgende Listing zeigt die Verwendung der Klasse File +und den Aufruf verschiedener Methoden: + + +

+ + + + + +
+ +
+001 /* TestFile.java */
+002 
+003 import java.io.*;
+004 import java.util.*;
+005 
+006 public class TestFile
+007 {
+008   public static void main(String[] args)
+009   {
+010     File fil = new File("TestFile.java");
+011     TestFile.printFileInfo(fil);
+012     fil = new File("..");
+013     TestFile.printFileInfo(fil);
+014   }
+015 
+016   static void printFileInfo(File fil)
+017   {
+018     System.out.println("Name= "+fil.getName());
+019     System.out.println("Path= "+fil.getPath());
+020     System.out.println("AbsolutePath= "+fil.getAbsolutePath());
+021     System.out.println("Parent= "+fil.getParent());
+022     System.out.println("exists= "+fil.exists());
+023     System.out.println("canWrite= "+fil.canWrite());
+024     System.out.println("canRead= "+fil.canRead());
+025     System.out.println("isFile= "+fil.isFile());
+026     System.out.println("isDirectory= "+fil.isDirectory());
+027     if (fil.isDirectory()) {
+028       String[] fils = fil.list();
+029       for (int i=0; i<fils.length; ++i) {
+030         System.out.println("  "+fils[i]);
+031       }
+032     }
+033     System.out.println("isAbsolute= "+fil.isAbsolute());
+034     System.out.println(
+035       "lastModified= "+(new Date(fil.lastModified()))
+036     );
+037     System.out.println("length= "+fil.length());
+038     System.out.println("");
+039   }
+040 }
+
+
+TestFile.java
+ +Listing 21.6: Verwendung der Klasse File

+ +

+Ein Aufruf des Programms liefert folgende Ausgabe: + +

+Name= TestFile.java
+Path= TestFile.java
+AbsolutePath= C:\ARC\DOKU\java\examples\TestFile.java
+Parent= null
+exists= true
+canWrite= true
+canRead= true
+isFile= true
+isDirectory= false
+isAbsolute= false
+lastModified= Sun Jan 05 17:15:56  1997
+length= 1242
+
+Name= ..
+Path= ..
+AbsolutePath= C:\ARC\DOKU\java\examples\..
+Parent= null
+exists= true
+canWrite= true
+canRead= true
+isFile= false
+isDirectory= true
+  makefile
+  html.cfg
+  ...
+  jdbc.sgml
+  tuning.sgml
+  reflection.sgml
+isAbsolute= false
+lastModified= Wed Jul 22 16:55:32 GMT+02:00 1998
+length= 0
+
+ +
+ + + +
 Titel  + Inhalt  + Suchen  + Index  + DOC  +Handbuch der Java-Programmierung, 5. Auflage, Addison +Wesley, Version 5.0.1 +
 <<  +  <   +  >   + >>  + API  +© 1998, 2007 Guido Krüger & Thomas +Stark, http://www.javabuch.de +
+ + + -- cgit v1.2.3