Rubrik: .NET | VB-Versionen: VB.NET | 01.09.04 |
Arbeiten mit Dateien und Ordnern in .NET, Teil 2 Teil 2 unseres Workshops beschäftigt sich näher mit der Directory- und File-Klasse, Laufwerke, isoliertem Speicher und einigen interessanten Hilfsfunktionen für die Analyse von Dateinamen. | ||
Autor: Ralf Ehlert | Bewertung: | Views: 30.762 |
Teil 2 unseres Workshops beschäftigt sich näher mit der Directory- und File-Klasse, Laufwerke, isoliertem Speicher und einigen interessanten Hilfsfunktionen für die Analyse von Dateinamen.
Informationen über Laufwerke ermitteln
Es gibt leider keine Klasse wie Drive, die Informationen über ein Laufwerk enthält. Dazu müssen wir uns den Namespace System.Management einmal genauer anschauen. Wir leisten erst einmal Vorarbeit, um uns die Arbeit für die eigentliche Informationsermittlung zu vereinfachen.
Eine Klasse für Laufwerke (Festplatten, CD/DVD-Laufwerke, Disketten,...)
Wir erstellen eine Klasse, mit der wir sehr komfortabel sehr viele Informationen von Laufwerken auslesen können. Dies müssen wir nur einmal machen, danach können wir unsere Klasse immer wieder verwenden.
Um den Namespace System.Management überhaupt benutzen zu können, müssen wir einen Verweis auf "System.Management" (Registerkarte .NET) hinzufügen.
Fügen Sie in einem Testprojekt einen Button hinzu und geben Sie folgenden Code ein:
Dim MClass As New ManagementClass(Nothing, "Win32_LogicalDisk", Nothing, " ") ' der letzte Parameter gibt den Namespace an MClass.GetStronglyTypedClassCode(CodeLanguage.VB, "C:\LogicalDisk.vb", "LogicalDisk")
Beim korrekten Ausführen sollten Sie eine Datei mit dem Namen "LogicalDisk.vb" auf Laufwerk C finden, welche eine Klasse enthält, die ein Laufwerk repräsentiert. Um diese einem Projekt hinzuzufügen, wählen Sie die Option "Vorhandenes Element hinzufügen".
Auflistung aller verfügbaren Laufwerke
Dim Searcher As New ManagementObjectSearcher("SELECT * FROM Win32_LogicalDisk") Dim Drive As ManagementObject For Each Drive In Searcher.Get() ListBox1.Items.Add(Drive("Name").ToString()) Next Drive
Informationen eines bestimmten Laufwerks ermitteln
Hier kommt unsere erstellte Klasse zur Funktion. Als Erstes legen wir eine Instanz an, welche das Laufwerk repräsentiert.
Dim Disk As New LogicalDisk.LogicalDisk(New _ ManagementPath("win32_LogicalDisk.DeviceId=""c:"""))
Hinweis: Falls Sie bei der Klassenerstellung als letzten Parameter einen anderen String übergeben haben, müssen Sie den Namespace entsprechend ändern.
Nun möchten wir zunächst wissen, ob das angegebene Laufwerk auch bereit ist, d.h. ob bei einem Diskettenlaufwerk eine Diskette eingelegt ist bzw. allgemein bei einem Wechselmedium, wie CD-Laufwerk, ein Datenträger eingelegt ist. Anschließend ermitteln wir den Speicherplatz insgesamt, sowie den noch freien Speicherplatz:
' Bereit? If Not Disk.IsVolumeDirtyNull Then ' Kapazität, sowie freien Speicherplatz in KB anzeigen MessageBox.Show("Gesamtkapazität (KB): " & _ Format(Convert.ToDecimal(Disk.Size) / 1024, "#,###") & vbCrLf & _ "Noch frei (KB): " & Format(Convert.ToDecimal(Disk.FreeSpace) / 1024, "#,###")) Else MessageBox.Show("Laufwerk nicht bereit.") End If
Um was für einen Laufwerkstyp handelt es sich eigentlich und welches Dateisystem wird verwendet? Diese Fragen beantworten uns die Eigenschaften DriveType und FileSystem:
Select Case Convert.ToInt32(Disk.DriveType) Case 2 MessageBox.Show("Diskette") Case 3 MessageBox.Show("Festplatte") Case 4 MessageBox.Show("Netzlaufwerk")</font> Case 5 MessageBox.Show("CD-Laufwerk") Case Else MessageBox.Show("Unbekannter Laufwerkstyp") End Select ' Welches Dateisystem wird verwendet? (z.B. NTFS oder FAT32) MessageBox.Show("Disk.FileSystem")
Sieht ziemlich kompliziert aus? Nur auf dem ersten Blick. In der If-Anweisung wird überprüft, ob das Laufwerk bereit ist. Falls es nicht bereit ist, wird true zurückgegeben. In der MessageBox-Anweisung passiert allerhand. Als erstes wird ein String ausgegeben, danach soll die Gesamtkapazität des Laufwerks ausgegeben werden in KB. Dies geschieht mit der Disk.Size(). Nur liefert diese die Größe in Bytes, wir wollen aber Kilobyte. Also, durch 1024 dividieren und wir haben KB. Nur geht dies bei Option Strict On nicht, da der /-Operator für System.UInt64 nicht definiert ist (soll sich mit Whidbey ändern). Da Disk.Size()diesen Typ zurück liefert, müssen wir ihn konvertieren, und zwar in Decimal, um genügend Platz zu haben. Dies können wir mit Convert.ToDecimal() erreichen. Nun können wir dividieren. Das Ganze wird mit der Format-Funktion noch schön formatiert, das selbe Schauspiel für den freien Speicherplatz und die Meldung ist (endlich) fertig.
Stammverzeichnis eines Laufwerks ermitteln:
MessageBox.Show("Stammverzeichnis: " & Disk.Name & "\")
Mit der Name-Eigenschaft (readonly) wird Stammverzeichnis ohne Backslash zurückgegeben, daher wurde der Backslash hinzugefügt.
Abschließend möchten wir noch die Datenträger-Bezeichnung (VolumeName), sowie die Seriennummer des Laufwerks ermitteln. Und das geht so:
' Datenträgerbezeichnung MessageBox.Show(Disk.VolumeName) ' Seriennummer des Datenträgers MessageBox.Show(Disk.VolumeSerialNumber)
Mehr über die Directory-Klasse
In diesem Abschnitt wird die Directory-Klasse unter die Lupe genommen. Folgendes Beispiel listet in eine Listbox alle Ordner auf ein Laufwerk (ohne enthaltende Unterordner!) auf:
' Auflistung aller Ordner auf Laufwerk C: Dim Directories As String() = Directory.GetDirectories("C:\") Dim Directory As String For Each Directory In Directories ListBox1.Items.Add(Directory) Next
Mit der GetFiles-Methode erhalten Sie ein String-Array mit den Namen aller enthaltender Dateien:
' Alle Dateien im Stammverzeichnis C: anzeigen Dim Files As String() = Directory.GetFiles("C:\") Dim File As String For Each File In Files ListBox1.Items.Add(File) Next
Informationen über Ordner ermitteln
Ordner-Attribute lesen und setzen
Über die Attributes-Eigenschaft der DirectoryInfo-Klasse kann man die Attribute eines Ordners sowohl lesen als auch neu setzen:
' DirectoryInfo-Klasse erstellen, um Attribute lesen/setzen können Dim DInfo As New DirectoryInfo("C:\Test") ' Versteckt? If CBool(DInfo.Attributes And FileAttributes.Hidden) Then MessageBox.Show("Versteckt!") Else DInfo.Attributes = DInfo.Attributes Or FileAttributes.Hidden End If
Um ein gesetztes Attribute zu löschen, verwenden Sie den Xor-Operator:
DInfo.Attributes = Dinfo.Attributes Xor FileAttributes.Hidden
Erstellungsdatum, letzte Änderung und Datum des letzten Zugriffes ermitteln
' Erstellungsdatum MessageBox.Show("Erstellungsdatum: " & Directory.GetCreationTime("C:\Test\").ToLongDateString) ' Letzter Zugriff MessageBox.Show(Directory.GetLastAccessTime("C:\Test\").ToShortDateString & ", " & _ Directory.GetLastAccessTime("C:\Test\").ToShortTimeString) ' Letzte Änderung MessageBox.Show(Directory.GetLastWriteTime("C:\Test\").ToLongDateString & ", " & _ Directory.GetLastWriteTime("C:\Test\").ToShortTimeString)
Laufwerksbuchstabe, Name des Ordners, vollständiger Pfad usw.
Diese Informationen liefert uns die DirectoryInfo-Klasse.
Dim Folder As New DirectoryInfo("C:\Test\") ' Laufwerksbuchstabe MessageBox.Show(Folder.Root.ToString) ' Ordnername (ohne Pfadangabe) MessageBox.Show(Folder.Name) ' vollständiger Pfad MessageBox.Show(Folder.FullName)
Übergeordneten Ordner ermitteln
Sie möchten wissen, ob es sich bei dem Ordner um den Root-Ordner handelt oder ob es einen übergeordneten Ordner gibt? Kein Problem bei .NET
If Not DInfo.Name = DInfo.Root.ToString Then MessageBox.Show(DInfo.Parent.Name) End If
Gibt es weitere Unterordner? Diese Frage beantwortet GetDirectories() aus der Directory- oder DirectoryInfo-Klasse.
Dim Folders() As String = Directory.GetDirectories("C:\Temp\") If Folders.GetLength(0) = 0 Then MessageBox.Show("Der Ordner enthält keine weitere Unterordner.") Else MessageBox.Show("Der Ordner enthält " & Folders.GetLength(0) & " Unterordner.") End If
Mehr über die File-Klasse
Wie bereits gezeigt, kann man mit der GetFiles()-Methode der Directory-Klasse alle Dateien auflisten. Möchte man einen Dateifilter einsetzen, benutzt man eine Überladung der GetFiles()-Methode. Folgendes Beispiel listet alle Textdateien (.txt) in eine Listbox auf:
' nur TXT-Dateien in eine Listbox anzeigen Dim File As String Dim Files() As String = Directory.GetFiles("C:\Temp\", "*.txt") For Each File In Files ListBox1.Items.Add(File) Next
Die Anzahl der Dateien in einen Verzeichnis lässt sich z.B. mit folgendem Code bestimmen (Unterordner werden nicht berücksichtigt):
' Anzahl der Dateien Dim File As String Dim Files() As String = Directory.GetFiles("C:\Temp\") Dim Counter As Integer = 0 For Each File In Files Counter += 1 Next MessageBox.Show(Counter.ToString)
Informationen einer bestimmten Datei ermitteln
Die FileInfo-Klasse verfügt im Großen und Ganzen über die selben Methoden wie die Directory-Klasse/ DirectoryInfo-Klasse, so das folgende Tabelle mit je einem kleinen Beispiel ausreichend sein sollte:
Aufgabe | Methode/Funktion | Beispiel |
Attribute abfragen/setzen | FileInfo.Attributes | FInfo.Attributes = FInfo.Attributes Or FileAttributes.Compressed |
Datei kopieren | FileInfo.CopyTo | FInfo.CopyTo("C:\Temp1\Test.txt") |
Datei verschieben | FileInfo.MoveTo | FInfo.MoveTo("C:\Test\Testdatei.txt") |
Datei umbenennen | FileInfo.MoveTo | FInfo.MoveTo("C:\Test\Test.txt") |
Datei löschen | FileInfo.Delete | FInfo.Delete() |
Erstellungsdatum | FileInfo.CreationTime | MessageBox.Show(FInfo.CreationTime.ToString) |
Letzter Datei-Zugriff | FileInfo.LastAccessTime | MessageBox.Show(FInfo.LastAccessTime.ToString) |
Datum der letzen Änderung | FileInfo.LastWriteTime | MessageBox.Show(FInfo.LastWriteTime.ToString) |
Vollständiger Pfad | FileInfo.FullName | MessageBox.Show(FInfo.FullName) |
Dateierweiterung | FileInfo.Extension | MessageBox.Show(FInfo.Extension) |
Dateigröße | FileInfo.Lenght | MessageBox.Show("Dateigröße: " & FInfo.Length.ToString & " Bytes") |
Übergeordneter Ordner | FileInfo.Directory | MessageBox.Show(FInfo.Directory.ToString) |
Hinweis: Beim Kopieren oder Verschieben müssen Sie den (neuen) Namen der Datei mit Erweiterung angeben, d.h. Sie können eine Datei gleichzeitigkopieren/verschieben und umbenennen. Das Zielverzeichnis muss existieren!
Isolierter Speicher
Aufgabe des isolierten Speichers
Der isolierte Speicher ist dazu da, vertrauenswürdige Informationen zu schützen und verhindert den Zugriff von nicht vertrauenswürdigem Code. Man kann in isolierten Speicher schreiben und lesen wie in einen normalen Stream. Die Verwendung von StreamReader und StreamWriter ist möglich, wodurch das Schreiben und Lesen einfach ist, da dies schon bekannt ist. Folgendes Beispiel soll die Verwendung von isolierten Speicher zeigen. Es wird ein Speicher erstellt, die maximale Größe wird zurückgegeben, es wird ein Stream erzeugt und in diesen geschrieben, anschließend wird gefragt, ob der geschriebene String gelesen werden soll (bei Ja->Ausgabe), danach wird er geschlossen, eine Meldung wird ausgegeben und der Speicher wird gelöscht.
' Variable, die den isolierten Speicher repräsentiert ' auf Speicher soll durch Assembly (Anwendung) und User (Benutzer) zugegriffen werden Dim Iso As IsolatedStorageFile = IsolatedStorageFile.GetStore( _ IsolatedStorageScope.User Or IsolatedStorageScope.Assembly, Nothing, Nothing) ' maximale Speichergröße in Megabyte ermitteln und mit 'Format' formatieren MessageBox.Show(Format(Convert.ToDecimal(Iso.MaximumSize) / 1024 / 1024, "#,###")) ' ein Verzeichnis in den isolierten Speicher erstellen Iso.CreateDirectory("privat") ' einen Stream für isolierten Speicher anlegen und eine Datei erzeugen Dim FStream As New IsolatedStorageFileStream("privat\test.txt", _ FileMode.OpenOrCreate, FileAccess.ReadWrite, Iso) ' einen StreamWriter erzeugen Dim SWriter As New StreamWriter(FStream) ' in den Stream schreiben SWriter.WriteLine("Dies ist eine Testdatei in einen isolierten Speicher.") ' StreamWriter und Stream schließen SWriter.Close() FStream.Close() ' Fragen, ob Datei gelesen werden soll Dim Answer As DialogResult = MessageBox.Show("Lesen?", "Frage", _ MessageBoxButtons.YesNo, MessageBoxIcon.Question) FStream = New IsolatedStorageFileStream("privat\test.txt", _ FileMode.Open, FileAccess.Read, Iso) If Answer = DialogResult.Yes Then ' Ja, Datei lesen und ausgeben Dim SReader As New StreamReader(FStream) Dim Contents As String = SReader.ReadToEnd SReader.Close() SReader = Nothing MessageBox.Show(Contents) End If MessageBox.Show("Der isolierte Speicher wird geschlossen.") ' Stream schließen FStream.Close() FStream = Nothing ' isolierten Speicher schließen Iso.Dispose() Iso.Close() MessageBox.Show("Isolierter Speicher wird gelöscht", "Info", _ MessageBoxButtons.OK, MessageBoxIcon.Information) ' vorhandenen isolierten Speicher öffnen Iso = IsolatedStorageFile.GetUserStoreForAssembly() ' isolierten Speicher löschen Iso.Remove(IsolatedStorageScope.User) Iso.Dispose() Iso.Close() MessageBox.Show("Isolierter Speicher gelöscht.")
Der Code dürfte durch die Kommentare selbsterklärend sein.
Spezielle Ordner
Der letzte Abschnitt soll zeigen, wie Sie den Ort von speziellen Ordnern ermitteln. Hier ein Beispiel, das den Speicherort vom System-Verzeichnis ermittelt und ausgibt.
' System-Verzeichnis ausgeben Dim System As String = Environment.GetFolderPath(Environment.SpecialFolder.System) MessageBox.Show(System)
Hier eine kleine Tabelle mit den wichtigsten "Special Folders":
Spezialordner | SpecialFolder-Konstante |
Cookies | SpecialFolder.Cookies |
Desktop | SpecialFolder.Desktop |
Favoriten | SpecialFolder.Favorites |
Verlauf | SpecialFolder.History |
Eigene Dateien | SpecialFolder.Personal |
Programme | SpecialFolder.Programs |
Startmenü | SpecialFolder.StartMenu |
Autostart | SpecialFolder.Startup |
System | SpecialFolder.System |
Die Path-Klasse
Die Path-Klasse führt String-Operationen an Verzeichnis- und Dateipfaden durch. Folgendes Beispiel ändert die Erweiterung von .TXT nach .RTF:
' Erweiterung ändern Dim Extension As String = Path.ChangeExtension("C:\Kon.txt", ".rtf")
Um zwei Pfade zu kombinieren, steht uns die Combine-Methode zur Verfügung:
' 2 Pfade kombinieren Dim Pfad1 As String = "C:\Test\" Dim Pfad2 As String = "Test1\Test.txt" MessageBox.Show(Path.Combine(Pfad1, Pfad2))
Um den Pfad einer Datei/eines Ordners zu erhalten, bietet sich die GetDirectoryName-Methode an:
' Pfad einer Datei/Verzeichnis ausgeben MessageBox.Show(Path.GetDirectoryName("C:\Temp\Test.txt"))
Um die Erweiterung einer Datei auszulesen, verwenden wir die GetExtension-Methode:
' Erweiterung ausgeben MessageBox.Show(Path.GetExtension("C:\Temp\Test.txt"))
Um nur den Dateinamen aus einer Pfadangabe zu extrahieren, stehen uns GetFileName und GetFileNameWithoutExtension zur Verfügung:
' Dateinamen aus Pfadangabe einmal mit und einmal ohne Erweiterung MessageBox.Show(Path.GetFileName("C:\Temp\Test.txt") & vbCrLf & _ Path.GetFileNameWithoutExtension("C:\Temp\Test.txt"))
Um den vollständigen (absoluten) Pfad zu erhalten wurde GetFullName geschaffen:
' Vollständigen Pfad zurückgeben MessageBox.Show(Path.GetFullName("C:\Temp\Test.txt"))
Möchten Sie das Stammverzeichnis ermitteln? Mit GetPathRoot ein Kinderspiel:
' Stammverzeichnis ausgeben MessageBox.Show(Path.GetPathRoot("C:\Temp\Test.txt"))
GetTempPath gibt den Pfad für temporäre Dateien zurück. Mit GetTempFileName kann man sehr leicht temporäre Dateien erstellen und verwenden.
' Beispiel für temporäre Dateien Dim TempFile As String = Path.GetTempFileName() Dim Stream As New FileStream(TempFile, FileMode.Open, FileAccess.Write) Dim StreamWriter As New StreamWriter(Stream) StreamWriter.WriteLine("Testzeile") StreamWriter.Close() Stream = New FileStream(TempFile, FileMode.Open, FileAccess.Read) Dim StreamReader As New StreamReader(Stream) Dim Contents As String = StreamReader.ReadToEnd StreamReader.Close() Stream.Close() MessageBox.Show(Contents) File.Delete(TempFile)
Ausblick auf Teil 3
Nun, da wir (fast) alle Methoden für die Dateibehandlung des .NET Frameworks besprochen haben, wäre es sicherlich hilfreich, unser "neues" Wissen in einem kleineren (oder auch größeren) Projekt anzuwenden.
Und genau das haben wir vor! Im letzen Workshop-Teil "basteln" wir einen kleinen Datei-Commander.
Unseren Datei-Commander wollen wir hierbei mit folgenden Features ausstatten:
- Zwei Fenster für die Anzeige der Ordner/Dateinamen
- Laufwerk- und Verzeichniswechsel
- Filter-Funktion für Dateinamen
- Anzeige von Datum/Uhrzeit, Dateigröße und Attribute
- Ändern von Dateiattributen
- Kopieren, Löschen und Verschieben von Dateien
- integrierter Editor zum Bearbeiten von Textdateien
- Erstellen von neuen Textdateien
Sie sehen schon: Wir werden wirklich alle Funktionen des .NET Frameworks ausschöpfen.