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

Liste

.NET 2.0 (1)
.NET Allgemein (16)
.NET Fu (5)
ADO.NET (11)
Aprilscherz (3)
ASP Grundlagen (44)
ASP Tricks (83)
ASP.NET (44)
ASPIntranet.de (5)
C# (28)
Datenbank (44)
Dokumentation (4)
IIS 6.0 (1)
Komponenten (29)
Optimierung (10)
Server (21)
Sicherheit (34)
Tee Off (6)
VB.NET (6)
WAP (8)
Web Services (11)
XML (9)

RSS 2.0 - Die neuesten fünf Artikel auf AspHeute.com


 

Suchen





 

English Articles
Chinese Articles
Unsere Autoren
 
Link zu AspHeute
Impressum
Werben
Anfragen

Directory Browsing a la .NET

Geschrieben von: Christoph Wille
Kategorie: ASP.NET

Aus den "guten alten Zeiten" des ASP Programmierens dürfte sehr vielen das FileSystemObject Objekt in Erinnerung sein. Es erlaubt Zugriff auf das Dateisystem für Lesen, Schreiben und Directory Browsing. Allerdings ist Objektmodell alles andere als optimal, und bei binären Dateien ist das Ende der Fahnenstange erreicht, bevor man am Ziel ist - es geht schlicht und ergreifend nicht.

Auch sonst gibt es einige Funktionen und Eigenschaften, die ich sehr gerne gehabt hätte. Es scheint so, als würden diese Wünsche mit den .NET Framework Klassen im System.IO Namespace in Erfüllung gehen. Die Dateiverarbeitung war nie einfacher, und vor allem nie leistungsfähiger.

Für diesen Artikel habe ich einen Teil der Dateiverarbeitung herausgepickt: das Auflisten von Dateien und Ordnern. Ich habe einige nette Scripts gebastelt, die man später in eigenen Applikationen einsetzen kann. Weitere Artikel werden sich mit dem Lesen und Schreiben von Dateien befassen.

Voraussetzung um den Sourcecode dieses Artikels verwenden zu können ist eine Installation des Microsoft .NET Framework SDK's auf einem Webserver. Weiters setze ich voraus, daß der Leser die Programmiersprache C# zu einem gewissen Grad beherrscht - es finden sich etliche Artikel auf diesem Server, um das notwendige Wissen zu erlernen.

Laufwerke aufzählen

Das Erste, was wir herausfinden sollten ist, welche Laufwerke eigentlich so am Rechner für uns zum Herumstöbern verfügbar sind (listdrives.aspx):

<% @Page Language="C#" %>
<% @Import Namespace="System.IO" %>
<%
string[] achDrives = Directory.GetLogicalDrives();
int nNumOfDrives = achDrives.Length;

Response.Write("<ul>");
for (int i=0; i < nNumOfDrives; i++)
{
 Response.Write("<li><a href=\"listdir.aspx?dir=");
 Response.Write(Server.UrlEncode(achDrives[i]));
 Response.Write("\">" + achDrives[i]);
 Response.Write("</a><br>");
}
Response.Write("</ul>");
%>

Im System.IO Namespace (mit der @Import Namespace Anweisung eingebunden) gibt es eine Klasse namens Directory. Dieses repräsentiert Funktionalitäten die man mit einem Verzeichnis brauchen kann, und die Klasse enthält auch die statische (ohne Objektinstanz aufrufbare) Methode GetLogicalDrives. Diese liefert uns ein Array von Strings, die die Laufwerksbuchstaben enthalten.

Natürlich habe ich es nicht bei einer einfachen Auflistung der über GetLogicalDrives erhaltenen Laufwerke belassen - ich habe gleich einen Link auf eine weiterführende Seite eingebaut, die dann Aufschluß über den Inhalt des Root-Verzeichnisses des Laufwerks gibt.

Verzeichnisse und Dateien auflisten

Jetzt sind wir in einem Verzeichnis. Was interessiert uns dort? Zum Beispiel die Unterverzeichnisse und Dateien, als auch Eigenschaften des Verzeichnisses selbst (Erstellungsdatum, etc). Das folgende Sourcodelisting der Datei listdir.aspx zeigt, wie man die geforderte Funktionalität implementieren könnte:

<% @Page Language="C#" %>
<% @Import Namespace="System.IO" %>
<%
string strDir2List = Request.QueryString.Get("dir");
DirectoryInfo thisOne = null;

try
{
  thisOne = new DirectoryInfo(strDir2List);
  // Auslesen der Eigenschaften der Verzeichnisses
  Response.Write("<p>Erzeugung: " + 
     thisOne.CreationTime.ToString() + "</p>");

  DirectoryInfo[] subDirectories = thisOne.GetDirectories();
  Response.Write("<ul>");
  for (int i=0; i < subDirectories.Length; i++)
  {
    Response.Write("<li><a href=\"listdir.aspx?dir=");
    Response.Write(Server.UrlEncode(subDirectories[i].FullName));
    Response.Write("\">" + subDirectories[i].Name);
    Response.Write("</a><br>");
  }
  Response.Write("</ul>");
  
  FileInfo[] theFiles = thisOne.GetFiles();
  Response.Write("<ul>");
  for (int i=0; i < theFiles.Length; i++)
  {
    Response.Write("<li><a href=\"showfile.aspx?file=");
    Response.Write(Server.UrlEncode(theFiles[i].FullName));
    Response.Write("\">" + theFiles[i].Name);
    Response.Write("</a><br>");
  }
  Response.Write("</ul>");
}
catch (Exception e)
{
  Response.Write("Zugriff nicht möglich, Fehler: <i>");
  Response.Write(e.ToString() + "</i>");
  Response.End();
}
%>

Das Auslesen der Verzeichnisse funktioniert mittels der GetDirectories Methode, die mir ein Array von DirectoryInfo Objekten liefert, mit denen ich dann meine gewünschte Funktionalität aufbauen kann (zB wie hier ein weiterer Link für den Drill-Down). Gleiches gilt für die GetFiles Methode, die ein Array von FileInfo Objekten liefert. Mehr zu diesem in der nächsten Sektion.

Wozu brauche ich bitte schön das Exception Handling? Nun, es könnte ja sein, daß ich auf etwas zugreife, wo ich nicht hingreifen darf, und dann bekommt man eine auf die Finger (dieser Fall dürfte auch dem Real-Life bekannt sein...). Im Ernst: es könnten zum Beispiel die NTFS Rechte für den aktuellen Benutzer nicht ausreichend sein (Listen verboten).

Dateiinformationen ausgeben

Jetzt sind wir auf der Dateiebene. Natürlich hat eine Datei eine Menge von Eigenschaften, und das folgende Beispiel showfile.aspx präsentiert nur eine Untermenge. Ein Blick in die Dokumentation enthüllt den Rest dessen, was ich zur Kürzung des Scripts ausgelassen habe.

<% @Page Language="C#" %>
<% @Import Namespace="System.IO" %>
<html>
<head><title>File Info</title></head>
<body>
<%
string strFile2Show = Request.QueryString.Get("file");
FileInfo thisOne = new FileInfo(strFile2Show);
%>
<table>
<tr><td>Name:</td><td><%=thisOne.Name%></td></tr>
<tr><td>Pfad:</td><td><%=thisOne.FullName%></td></tr>
<tr><td>Verzeichnis:</td><td><%=thisOne.DirectoryName%></td></tr>
<tr>
  <td>Erstellung:</td>
  <td><%=thisOne.CreationTime.ToString()%></td>
</tr>
<tr>
  <td>Länge:</td>
  <td><%=thisOne.Length.ToString()%> Bytes</td>
</tr>
<tr>
  <td>Letzter Zugriff:</td>
  <td><%=thisOne.LastAccessTime.ToString()%></td>
</tr>
<tr>
  <td>Letzte Modifikation:</td>
  <td><%=thisOne.LastWriteTime.ToString()%></td>
</tr>
</table>

<%
StreamReader theReader = thisOne.OpenText();
char[] theBuffer = new char[255];
int nRead = theReader.ReadBlock(theBuffer, 0, 255);
Response.Write("<pre>");
Response.Write(Server.HtmlEncode(new String(theBuffer,0,nRead)));
Response.Write("</pre>");
%>

</body>
</html>

Am Ende des Scripts habe ich einen kurzen Ausflug in Richtung Dateiauslesen unternommen, um zu demonstrieren, wie einfach das ist. Zuerst öffne ich ein StreamReader Objekt, lege einen Puffer an, fülle den Puffer mit der ReadBlock Methode und gebe den eingelesenen Block dann HTML-encoded mit an den Client aus. Und schon hat man eine kleine "Dateivorschau". Nicht gerade weltbewegend, aber es demonstriert bereits, wie einfach auch das Arbeiten mit den Inhalten von Dateien ist.

Rekursives Auflisten eines Verzeichnisses

Zu guter Letzt habe ich noch ein kleines Programm zum Erzeugen eines Verzeichnisbaums in Petto. Wie die Überschrift schon verrät, wird der Baum rekursiv erzeugt - man braucht also eine Funktion, die rekursiv aufgerufen werden kann. Im Beispiel recursivelisting.aspx heißt diese RecursiveDump:

<% @Page Language="C#" %>
<% @Import Namespace="System.IO" %>
<%
string strDir2List = Request.QueryString.Get("dir");
DirectoryInfo thisOne = new DirectoryInfo(strDir2List);

Response.Write("<pre>");
RecursiveDump(thisOne, 0);
Response.Write("</pre>");
%>

<script language="C#" runat="server">
void RecursiveDump(DirectoryInfo theDir, int nLevel)
{
  DirectoryInfo[] subDirectories = theDir.GetDirectories();
  for (int i=0; i < subDirectories.Length; i++)
  {
    Response.Write(new String(' ',nLevel));
    Response.Write(subDirectories[i].Name + "\r\n");
    RecursiveDump(subDirectories[i], nLevel+1);
  }
}
</script>

Wie immer habe ich es mir besonders einfach gemacht, und verwende einfach Leerzeichen um den Baum zu generieren. Damit man's in HTML auch sieht, muß man daher ein <PRE> Tag verwenden - sonst werden die Leerzeichen geschluckt.

Die Funktion selbst hat 2 Parameter: ein DirectoryInfo Objekt, und eine Integervariable, die die aktuelle Ebene bezeichnet. Es werden für die aktuelle Ebene die Unterverzeichnisse ausgelesen (mit GetDirectories), und dann mit einer for Schleife ausgegeben. Für jedes DirectoryInfo Objekt wird die Funktion RecursiveDump aufgerufen, und die Ebene um 1 erhöht.

Das Ergebnis kann dann so aussehen (Achtung: wenn man ein ganzes Laufwerk aufbauen läßt, so kann dies schon einige Zeit in Anspruch nehmen!):

Schlußbemerkung:

In diesem Artikel habe ich drei Objekte aus dem System.IO Namespace präsentiert: Directory, DirectoryInfo und FileInfo. Obwohl ich sie "nur" zum Ausgeben einfacher Verzeichnis- und Dateiinformationen verwendet habe, sind diese Objekte die Basis zur Dateiverarbeitung wie Lesen und Schreiben. Dazu aber mehr in einem späteren Artikel.

Download des Codes

Klicken Sie hier, um den Download zu starten.

Verwandte Artikel

Dateien lesen in ASP.NET
Dateien umbenennen
Ein Touch-Utility in C#
Eine Klasse für sich - die .NET Zip Library
Exception Handling in C#
Online File Management System mit ASP.NET und C# - Teil 1
Online File Management System mit ASP.NET und C# - Teil 2
Verwendung von Arrays in C#
Verzeichnisbäume rekursiv generieren

Links zu anderen Sites

Die aspDEdotnet Diskussionsliste
Download ASP.NET

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.

Eine weitere sehr hilfreiche Resource ist das deutsche ASP.NET Wiki, das als zentrale Anlaufstelle für Tips, Tricks, Know How und alles Nützliche was man in seinem Alltag als (ASP).NET-Entwickler so braucht und entdeckt gedacht ist.

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.

Bewerten Sie diesen Artikel
 Sehr gut   Nicht genügend  
   1  2  3  4  5  
 

  
   Für Ausdruck optimierte Seite

©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.