Glengamoi (Forum) · AspHeute · .NET Heute (RSS-Suche) · AspxFiles (Wiki) · .NET Blogs

Verzeichnisbäume rekursiv generieren

Geschrieben von: Christian Mairoll
Kategorie: ASP Grundlagen

This printed page brought to you by AlphaSierraPapa

Ob im Intranet oder zur vereinfachten Fernwartung eines ASP Web Servers, Ordnerauflistungen können von vielerlei Nutzen sein. Um einen Ordner samt seinen Unterordnern in gewohnter Weise darstellen zu können, benötigt man rekursive Aufrufe. Heute wollen wir uns einen Verzeichnisbaum eines definierten Ordners erstellen, der die selben Möglichkeiten bietet, wie der Windows-Explorer Baum.

Methoden zum Auflisten von Ordnern

Um eine Auflistung alle Unterordner eines bestimmten Ordners zu bekommen, benötigt man lediglich das FileSystemObject. Folgendes Listing zeigt, wie mit der GetFolder Methode eine Liste aller Unterordner erzeugt wird (listFolder.asp).

<%
'FileSystemObject in oFso anlegen 
Set oFso = Server.CreateObject("Scripting.FileSystemObject")

'Folder-Objekt mit GetFolder erzeugen
Set oFolder = oFso.GetFolder("c:\winnt\")

'Schleife zum Durchlaufen alle Unterordner von oFolder
For Each oSubFolder in oFolder.SubFolders
    Response.Write oSubFolder.Name & "<br>"
Next

'Resourcen freigeben
Set oFolder = nothing
Set oFso = nothing
%>

Das Scripting.FileSystemObject ermöglicht den Zugriff auf Ordner und Dateien. Die Möglichkeiten reichen hier von Ordner- und Dateiattributen anzeigen, bis hin zu deren Inhalt bearbeiten zu können. Jedoch einen Schwachpunkt hat das FileSystemObject für ASP-Entwickler: Binäre Dateien lassen sich nicht sinnvoll lesen und schreiben (z.B. Bildformate). Die Verwendung bleibt somit auf ASCII-Dateien (z.B. txt, html, xml, ini, etc.) beschränkt.

Eine vollständige Dokumentation der Scripting-Komponente finden Sie bei Microsoft.

Eine einfache Baumstruktur generieren

Zunächst ein Beispiel für einen einfachen serverseitig abgebildeten Verzeichnisbaum. Die Verschachtelung des Baumes erfolgt mit einem rekursiven Aufruf. Die vollständige Implementierung finden Sie in der Datei simpleTree.asp.

Als erstes benötigen wir das FileSystemObject.

Set oFso = Server.CreateObject("Scripting.FileSystemObject")

Dann legen wir den Startordner fest, ab dem der Baum beginnen soll. Achtung: Wenn Sie hier z.B. c:\ angeben, kann der Aufruf der Seite mehrere Minuten dauern, da alle Ordner auf dem Laufwerk aufgelistet werden.

sRootFolder = "c:\winnt\"

Damit wir später im Code nicht ständig die kompletten img-Tags verwenden müssen, legen wir zur Vereinfachung Konstanten an.

CONST FLD_CLOSE = "<img src=""FldClose.gif"" border=""0"">"
CONST FLD_OPEN  = "<img src=""FldOpen.gif"" border=""0"">"
CONST LINE_L    = "<img src=""LineL.gif"" border=""0"">"
CONST LINE_T    = "<img src=""LineT.gif"" border=""0"">"
CONST LINE_I    = "<img src=""LineI.gif"" border=""0"">"
CONST WHTSPACE  = "<img src=""WhtSpace.gif"" border=""0"">" 

Ebenso für die Tabellen. Jede Zeile besteht aus einer Tabelle mit zwei Spalten. Dies ist eine einfache Methode, um die Grafiken und den dabeistehenden Text (in diesem Fall den Ordnernamen) vertikal genau zu zentrieren. Ohne Tabelle verschiebt der Browser den Text leider ein wenig nach unten, wodurch ein unschöner Zwischenraum zwischen den Zeilen entsteht.

CONST TAB_START  = "<table border=0 cellspacing=0 cellpadding=0><tr><td>"
CONST TAB_MID    = "</td><td>"
CONST TAB_END    = "</td></tr></table>"

Als nächstes legen wir die Variablen für die beiden Bild-Pfade an. Diese sind beim Aufruf der Rekursion notwendig, um die richtige Darstellung der Ordner-Einrückung zur gewährleisten. Die Variable sImgPath1 enthält den normalen Pfad bis zur Ordner-Grafik. Die zweite Variable enthält den Pfad für den jeweils letzten Unterordner eines Ordners. Dieser hat die besonderen Eigenschaften, daß die letzte Grafik vor der Ordner-Grafik immer eine Ecke, und die Grafik davor immer eine Leer-Grafik sein muß.

Bei jedem Durchlauf der rekursiven Funktion wird der bisher vorhandene Pfad gespeichert, und die nächste Einrück-Stufe hinzugefügt. Daher werden die beiden Variablen sImgPath1 und sImgPath2 benötigt, welche die kompletten Bilderstrings bis zu den offenen oder geschlossenen Ordner-Grafiken speichern.

Die boolsche Variable bStart legt lediglich fest, daß beim ersten Aufruf der rekursiven Funktion der RootFolder angezeigt wird. Ist der RootFolder nämlich kein Unterordner des Laufwerkes, wird generell nichts angezeigt, da das Laufwerk selbst Teil der Drives-Collection ist, und nicht als Ordner angesehen wird.

bStart = true

Als nächstes wird die rekursive Funktion das erste mal aufgerufen und somit die Rekursion angestoßen.

Call getFolder(sRootFolder, sImgPath1, sImgPath2)

Die getFolder Funktion

Innerhalb der rekursiven getFolder Funktion schalten wir das Error-Handling ab. Grund dafür: Wenn die Funktion auf einen Ordner trifft, für den Sie keine Leserechte besitzt, bricht sie mit einer ASP-Fehlermeldung ab. Um dies zu vermeiden, und den Ordnernamen trotzdem anzuzeigen, wird das Error-Handling deaktiviert.

Function getFolder(sFolder, sImgPath1, sImgPath2)
On Error Resume Next

Das Ordner-Objekt und die Unterordner-Collection werden erzeugt.

Set oFolder = oFso.GetFolder(sFolder)
Set oSubFldColl = oFolder.SubFolders

Wenn der Ordner keine weiteren Unterordner mehr enthält, wird die Rekursion an diesem Punkt beendet.

If oSubFldColl.Count = 0 Then

Eine Zeile besteht aus folgenden Teilen:

  1. TAB_START: Der Anfang der Tabellenzeile
  2. sImgPath1: Der Bilderpfad bis zum Ordner-Bild
  3. FLD_CLOSE: Das Bild des geschlossenen Ordners
  4. TAB_MID: Abschluß der ersten und Beginn der zweiten Spalte der Tabelle.
  5. oFolder.Name: Der Name des Ordners. Beim ersten Durchlauf der Funktion der RootFolder. Hier könnte man z.B. einen Link auf eine Detailseite des Ordners einsetzen.
  6. TAB_END: Der Abschluß der Tabelle
Response.Write TAB_START & sImgPath1 & FLD_CLOSE & TAB_MID
If bStart Then
 Response.Write sRootFolder
 bStart = False
Else
 Response.Write oFolder.Name
End If
Response.Write TAB_END & vbCrLf

Enthält der Ordner weitere Unterordner, geht die Rekursion weiter.

 Else

Auch hier wieder das gleiche Schema wie oben, jedoch mit dem Unterschied, daß hier die Grafik des geöffneten Ordners verwendet wird, da noch weitere Unterordner bestehen.

Response.Write TAB_START & sImgPath1 & FLD_OPEN & TAB_MID
If bStart Then
 Response.Write sRootFolder
 bStart = False
Else
 Response.Write oFolder.Name
End If
Response.Write TAB_END & vbCrLf

Die For-Each Schleife geht alle Unterordner des aktuellen Ordners durch.

For Each oSubFld In oSubFldColl
sSubFldPath = sFolder & oSubFld.Name & "\"
i = i + 1
If i < oSubFldColl.Count Then
 'Bis auf den letzten Unterordner bei allen die T-Grafik verwenden
 Call getFolder(sSubFldPath, sImgPath2 & LINE_T, sImgPath2 + LINE_I)
Else
 'Beim letzten Unterordner die L-Grafik vor dem Ordner verwenden
 Call getFolder(sSubFldPath, sImgPath2 & LINE_L, sImgPath2 + WHTSPACE)
End If
Next

Erläuterung: Zunächst wird der gesamte Pfad des Unterordners gespeichert, da dieser beim nächsten Aufruf der Rekursion benötigt wird. Die Variable i zählt die Unterordner mit um rechtzeitig vor dem letzten Unterordner die aufzurufende Funktion ändern zu können.

Bis auf den letzten Unterordner wird beim Aufruf der rekursiven Funktion der normale Bilderpfad verwendet. Beim letzten Ordner muß der zweite Pfad verwendet werden, da hier zwei andere Abschluß-Grafiken eingesetzt werden müssen.

End If

Das wär's auch schon mit der rekursiven Funktion. Die getFolder-Methode ruft sich selbst immer wieder auf, bis keine weiteren Unterordner mehr vorhanden sind.

Set oFolder = Nothing
On Error GoTo 0

Die Resourcen werden wieder freigegeben und das Error-Handling wieder aktiviert.

End Function
%>

Erweiterte Baumstruktur generieren

Das vorige Beispiel zeigt, wie der Verzeichnisbaum serverseitig erzeugt wird. Wünschenswert wäre hier jedoch noch, daß der Baum genauso wie im Windows-Explorer dynamisch auf- und zuklappbar ist. Dies ließe sich nun entweder auch serverseitig realisieren, jedoch die ständigen Reloads der Seite würden unnötige Zeit des Users beanspruchen. Deshalb habe ich eine clientseitige Lösung gewählt.

Jeder Ordner samt seinen Unterordnern wird in einem eigenen fortlaufend durchnummerierten em-Tag geschrieben. Somit wird es möglich, den ganzen Ordner-Bereich mittels JavaScript aus- und einzublenden. Diese JavaScript-Funktion wird beim Klicken auf die "-" Grafik aufgerufen.

<a href="javascript:HideItem(OrdnerID)">Grafik</a>

Das Script zum Aus- und Einblenden sieht folgendermaßen aus:

<script language="JavaScript">
function HideItem(itemID)
{
    document.all['open'+itemID].style.display = "none";
    document.all['close'+itemID].style.display = "inline";
}
function ShowItem(itemID)
{
    document.all['open'+itemID].style.display = "inline";
    document.all['close'+itemID].style.display = "none";
}
</script>

Die zweite größere Erweiterung gegenüber dem einfachen Verzeichnisbaum ist eine weitere Unterscheidung beim Aufruf der rekursiven Funktion. Hier muß zusätzlich noch unterschieden werden, ob die Unterordner in der Ordner-Collection weitere Unterordner enthalten, um hier gegebenenfalls die "-" Grafik mit dem Link zum Ausblenden anzuzeigen.

Der vollständige SourceCode der jsTree.asp ist im heutigen Download enthalten. Aus Platzgründen wird auf eine vollständige Beschreibung der langen Fassung verzichtet. Bitte beachten Sie, daß das Zu- und Aufklappen eines Ordners nur mit dem Microsoft Internet-Explorer funktioniert. Es bleibt Ihnen überlassen, ob Sie auch eine Netscape-kompatible Routine mit layer bzw. div-Tags schreiben.

Weitere Möglichkeiten

Die oben gezeigten Beispiele zeigen, wie Sie einen Verzeichnisbaum eines bestimmten Ordners eines Server-Laufwerks erzeugen. Baumstrukturen sind aber nicht nur für File-Browsing interessant. Nach dem gleichen Schema können Sie nun z.B. ein Homepage-Menü oder ein Diskussionsforum mit den einzelnen Forums-Threads erstellen.

Übliche Baumstrukturen verfügen zwar über die notwendige Einrückung der Einträge (Nodes), jedoch nicht über eine ausgereifte grafische Darstellung der Einrückungen vor den Beschriftungen der Einträge, mit der Möglichkeit, einzelne Nodes ein- oder auszublenden.

Sicherheitsaspekte

Das FileSystemObject ist ein sehr mächtiges Werkzeug zum navigieren auf einem Laufwerk. Beachten Sie bitte, daß ohne ausreichende Absicherung des IUSR_<maschine>-Accounts jeder Besucher der Website alle Dateien des Laufwerks einsehen, bearbeiten oder gar löschen könnte.

Es ist daher zwingend notwendig, die NT-Rechte auf dem Server derart einzuschränken, daß der IUSR_<maschine> nicht weiter unterhalb des Webverzeichnisses zugreifen darf. Weitere Möglichkeiten sind natürlich Passwortabfrage vor dem Zugriff auf die Seite oder generell in der ASP-Applikation festlegen, daß der Besucher nur einen bestimmten Bereich browsen darf.

Schlußbemerkung

Die beiden Beispiele zum Erstellen eines Verzeichnisbaumes sollten als Grundlage dienen, um weitere Funktionen zu implementieren. Denkbar wäre ein vollständiger File-Browser, d.h. einen webbasierten Explorer mit Modulen zum Anzeigen und Editieren von Dateien. Natürlich gibt es auch fertige Tree-Komponenten im Web zum Download. Advantys bietet zum Beispiel die Gratis-Komponente TreeGen mit sehr umfangreichen Optionen an. VisualASP stellt ebenfalls eine Gratis-Testversion seiner TreeView Komponente zur Verfügung.

This printed page brought to you by AlphaSierraPapa

Download des Codes

Klicken Sie hier, um den Download zu starten.
http://www.aspheute.com/code/20011016.zip

Verwandte Artikel

Directory Browsing a la .NET
http:/www.aspheute.com/artikel/20000804.htm
Web-basiertes Dateimanagement mit dem ASP FileMan
http:/www.aspheute.com/artikel/20010507.htm

Links zu anderen Sites

Advantys TreeGen
http://www.treegen.com
ASP-Components Text2Tree
http://www.asp-components.de
iisCART iisTREE
http://www.iiscart.com
VisualASP TreeView
http://www.visualasp.com
Webintel.net Quick Tree View
http://www.webintel.net/components/qtv

 

©2000-2006 AspHeute.com
Alle Rechte vorbehalten. Der Inhalt dieser Seiten ist urheberrechtlich geschützt.
Eine Übernahme von Texten (auch nur auszugsweise) oder Graphiken bedarf unserer schriftlichen Zustimmung.