Verzeichnisbäume rekursiv generieren
Geschrieben von: Christian Mairoll 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 OrdnernUm 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 generierenZunä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 FunktionInnerhalb 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:
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 generierenDas 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öglichkeitenDie 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. SicherheitsaspekteDas 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ßbemerkungDie 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. Download des CodesKlicken Sie hier, um den Download zu starten. Verwandte Artikel
Directory Browsing a la .NET Links zu anderen Sites
Advantys TreeGen Wenn Sie jetzt Fragen haben...Wenn Sie Fragen rund um die in diesem Artikel vorgestellte Technologie haben, dann schauen Sie einfach bei uns in den Community Foren der deutschen .NET Community vorbei. Die Teilnehmer helfen Ihnen gerne, wenn Sie sich zur im Artikel vorgestellten Technologie weiterbilden möchten. Haben Sie Fragen die sich direkt auf den Inhalt des Artikels beziehen, dann schreiben Sie dem Autor! Unsere Autoren freuen sich über Feedback zu ihren Artikeln. Ein einfacher Klick auf die Autor kontaktieren Schaltfläche (weiter unten) und schon haben Sie ein für diesen Artikel personalisiertes Anfrageformular.
Und zu guter Letzt möchten wir Sie bitten, den Artikel zu bewerten. Damit helfen Sie uns, die Qualität der Artikel zu verbessern - und anderen Lesern bei der Auswahl der Artikel, die sie lesen sollten.
©2000-2006 AspHeute.com |