Weitere aktuelle Java-Titel finden Sie bei dpunkt.
 Inhaltsverzeichnis   Auf Ebene Zurück   Seite Zurück   Seite Vor   Auf Ebene Vor   Eine Ebene höher   Index


10.5.2

Abfragen der Dateiattribute


Durch Verwendung der Klasse File kann man folgende Operationen durchführen: Die meisten der Methoden von File dienen der Abfrage von Dateiattributen:

Tabelle 10.4: Einige Methoden, die Informationen über eine Datei liefern
getName()Dateinamen
length()Größe der Datei
getPath()Dateipfad
getAbsolutePath()absoluter Pfad
exists()Prüfung auf Existenz
canRead()Prüfung auf Existenz und Leserechte
canWrite()Prüfung auf Existenz und Schreibrechte
isDirectory()Prüfung auf Verzeichnis

Bei Dateipfaden werden auf verschiedenen Systemen zur Trennung der einzelnen Verzeichnisse oft unterschiedliche Zeichen verwendet. Bei UNIX ist dies z. B. /, bei Windows \. Die Klasse File besitzt ein Datenelement separator, in dem das systemabhängige Trennzeichen für Verzeichnisse vermerkt ist.

Analoges gilt für Pfadtrennzeichen: In Umgebungsvariablen (PATH) sind oft mehrere Dateien durch ein Trennzeichen getrennt aufgelistet. Auch dieses Trennzeichen ist systemabhängig: Bei UNIX ist es »:«, bei DOS »;«. Das systemabhängige Pfadtrennzeichen wird im Datenelement pathSeparator der Klasse File vermerkt.

Mit File erfolgt nicht nur der Zugriff auf Dateien, sondern auch auf Verzeichnisse. Hierzu wird statt des Dateinamens einfach der Name eines Verzeichnises angegeben.

Soll ein Verzeichnis angelegt werden, übergibt man dem Konstruktor von File den Namen des anzulegenden Verzeichnisses. Damit ist das Verzeichnis aber noch nicht erstellt. Die Erstellung des Verzeichnisses erfolgt erst duch Aufruf der Methode mkdir().

Es können auch ganze Verzeichnispfade erstellt werden. Hierfür besitzt die Klasse File die Methode mkdirs(). Beide Methoden haben den Ergebnistyp boolean. Hat die Erstellung eines Verzeichnisses aus irgendeinem Grund nicht geklappt, z. B. weil schon ein gleichnamiges Verzeichnis existiert, liefern die Methoden false.

Ein File kann mit jedem beliebigen Namen initialisiert werden. Wofür das File-Objekt letztendlich benutzt wird, kann der Programmierer auch später noch festlegen.

Ein Beispiel, das Attribute von Dateien abfragt, ist z. B. die Ausgabe eines Verzeichnisbaumes.

Dessen Anzeige kann man in Java folgendermaßen realisieren:
  import java.io.*;
  
  public class FileAttributeDemo
                 implements FilenameFilter {
    static PrintWriter stdout =
                 new PrintWriter(System.out, true);
  
    public static void main(String args[]) {
      try {
        // Überprüfung der Parameteranzahl
        if (args.length == 1) {
          // Überprüfen, ob ein
          // Verzeichnisname übergeben wurde
          File file = new File(args[0]);
          if (file.isDirectory()) {
            // Anzeigen des Verzeichnisbaumes
            FileAttributeDemo own = new FileAttributeDemo();
            own.showTree(file,0);
          }
          else {
            throw new IllegalParameterException(
                           args[0]+" is not a directory !");
          }
        }
        else
          throw new IllegalParameterException(
                          "Illegal number of parameters !");
      }
      catch(IllegalParameterException e) {
        stdout.println(e.getMessage());
        stdout.println(
              "Usage: java FileAttributDemo <directory>");
      }
    }
  
    public void showTree(File f, int level) {
      String list[] = null;
      try {
        String dir = "";
        // Einrückung um 'level' Ebenen
        for (int n=0; n < level;n++)
          dir+="        ";
        dir+=f.getName();
        if (f.canRead()) {
          list = f.list(this);
        }
        else
          dir+="  permission denied !";
        stdout.println(dir);
      }
      catch (NullPointerException e) {}
      if (list != null)
        for (int i=0; i < list.length; i++) {
          showTree(new File(
              f.getPath()+File.separator+list[i]),level+1);
        }
    }
  
    public boolean accept(File dir, String name) {
      // Überprüfen, ob der übergebene Name
      // ein Verzeichnis darstellt. Trifft dies zu,
      // wird 'true', sonst 'false' zurückgegeben
      File file = new File(dir.getPath()+File.separator+name);
      if (file.isDirectory())
        return true;
      return false;
    }
  
  }
  
  class IllegalParameterException extends Exception {
  
    public IllegalParameterException() {
      super();
    }
  
    public IllegalParameterException(String name) {
      super(name);
    }
  
  }
Obiger Applikation wird der Name des Verzeichnisses übergeben, dessen Unterstruktur angezeigt werden soll. Nach Prüfung der Parameter übernimmt die rekursive Methode showTree() die Ausgabe. In main() wird vom entsprechenden Verzeichnis ein File-Objekt angelegt und showTree() übergeben.

Als zusätzlichen Parameter besitzt showTree() eine Zahl, die anzeigt, wie tief sich das gerade bearbeitete Verzeichnis in der Verzeichnishierarchie befindet. Dieser Parameter wird verwendet, um den Namen eines Verzeichnisses, je nach Position innerhalb der Hierarchie, mehr oder weniger eingerückt auszugeben. Beim Aufruf von showTree() aus main() ist diese Zahl 0.

showTree() gibt als erstes den Namen des übergebenen Verzeichnisses in der durch level angegebenen Einrückungstiefe aus. Danach wird durch Aufruf von f.canRead() überprüft, ob das angegebene Verzeichnis lesbar ist. Ist dies der Fall, wird mit der Methode list() eine Liste von allen innerhalb des Verzeichnisses befindlichen Einträgen angefordert. Diese Liste enthält Verzeichnisse und Dateien. list() kann generell auf zwei Arten verwendet werden: FilenameFilter ist ein Interface, das die Anzahl von Einträgen, die von list() geliefert werden, einschränken kann.

Im obigen Beispiel wird ein FilenameFilter benutzt, um aus allen Einträgen nur die Verzeichnisse herauszufiltern. Dies wird folgendermaßen gemacht:

Eine Klasse, die FilenameFilter implementiert, besitzt die Methode accept(File dir, String name). In accept() wird festgelegt, welche Einträge eines Verzeichnisses bei einem Aufruf von list(FilenameFilter) geliefert werden. accept() bekommt als Parameter das Verzeichnis, in dem sich ein Eintrag befindet, und dessen Name übergeben.

In den Zeilen
  if (f.canRead()) {
    list = f.list(this);
wird die Methode list() des Verzeichnisses f aufgerufen, mit dem FilenameFilter der aktuellen Klasse als Parameter. Daraufhin wird für jeden Eintrag in diesem Verzeichnis automatisch die Methode accept() aufgerufen und als Parameter übergeben. Ist dieser Eintrag ein Verzeichnis, liefert accept() true, ansonsten false:
  public boolean accept(File dir, String name) {
    // Überprüfen, ob der übergebene Name
    // ein Verzeichnis darstellt. Trifft dies zu,
    // wird 'true', sonst 'false' zurückgegeben
    File file = new File(dir.getPath()+File.separator+name);
    if (file.isDirectory())
      return true;
    return false;
  }

Nun muss für die gefundenen Verzeichnisse dieselbe Prozedur ausgeführt werden, mit dem Unterschied, dass sich jedes so gefundene Verzeichnis eine Stufe tiefer in der Verzeichnishierarchie befindet:
  showTree(new File(
      f.getPath()+File.separator+list[i]),level+1);
Es ist zu beachten, dass der Aufruf von list() in einen try-catch-Block eingeschlossen ist, in dem eine NullPointerException abgefangen wird. Das liegt daran, dass bei bestimmten Dateien auf UNIX-Systemen, die keine Verzeichnisse sind, ein Aufruf von isDirectory() bei Verwendung des JDK 1.0 true liefert (z. B. alle Device-Dateien). Für diese Dateien wird natürlich, wie für Verzeichnisse auch, showTree() aufgerufen. Da aber in Wirklichkeit kein Verzeichnis vorliegt, löst ein Aufruf von list() eine NullPointerException aus. In diesem Beispiel wird auf diese Weise einfach die Ausgabe dieser besonderen Dateien unterdrückt.

isDirectory() liefert auf UNIX-Systemen auch bei Verknüpfungen (Links), die auf ein Verzeichnis weisen true als Ergebnis. Bis einschließlich JDK 1.2 ist es nicht möglich abzufragen, ob ein File-Objekt ein Verzeichnis oder eine Verknüpfung mit einem Verzeichnis repräsentiert. Aus diesem Grund wird das in diesem Abschnitt vorgestellte Beispielprogramm bei rekursiven Verzeichnisstrukturen, die durch Verknüpfungen realisiert sind, nicht terminieren.

Man könnte dieses Programm erweitern, so dass es die Verzeichnisstruktur mit Linien verbunden zeigt, um die zugehörigen Verzeichnisse besser kenntlich zu machen. Darauf wurde an dieser Stelle jedoch verzichtet, da der Umgang mit Dateien im Vordergrund steht.

Eine andere wichtige Anwendung des FilenameFilters ist die Auswahl von Dateien mit einer bestimmten Endung. Hierzu wird ein FilenameFilter betrachtet, der nur die Dateien mit der Endung .java liefert:
  public boolean accept(File dir, String name) {
    return name.endsWith(".java");
  }
Zur Überprüfung, ob ein Dateiname eine bestimmte Endung besitzt, wird die Methode endsWith() des betreffenden Strings mit der gewünschten Endung als Argument aufgerufen. Ist die Endung vorhanden, liefert endsWith() true, andernfalls false.

Das Ergebnis von endsWidth() wird dann anschließend als Funktionsergebnis von accept() zurückgegeben.


 Inhaltsverzeichnis   Auf Ebene Zurück   Seite Zurück   Seite Vor   Auf Ebene Vor   Eine Ebene höher   Index

Copyright © 2002 dpunkt.Verlag, Heidelberg. Alle Rechte vorbehalten.