1. Einführung
Wenn statische Klassen wie File und Directory wie ein universelles Schweizer Taschenmesser sind: immer zur Hand, lösen Aufgaben schnell, aber ohne Bindung an ein konkretes Objekt, dann sind FileInfo und DirectoryInfo eher personalisierte Werkzeuge: sie werden für eine konkrete Datei bzw. einen konkreten Ordner erstellt, "wissen" viel über diese und erlauben bequemeres und flexibleres Arbeiten, besonders bei mehrfachen Operationen am selben Objekt.
Instanzklassen halten Details zu einem konkreten Dateisystemobjekt, und nach dem ersten Laden der Properties muss man nicht zwingend wieder aufs Dateisystem zugreifen (außer das Objekt ist veraltet).
- FileInfo — für die Arbeit mit einer konkreten Datei.
- DirectoryInfo — für die Arbeit mit einem konkreten Verzeichnis (Ordner).
Sie enthalten Properties und Methoden, die detaillierte Informationen liefern (Größe, Erstellungsdatum, Extension, verfügbare Attribute) und Aktionen am File/Ordner ermöglichen: kopieren, löschen, verschieben usw.
Wie FileInfo und DirectoryInfo aufgebaut sind
Beide Klassen erben von einer gemeinsamen abstrakten Klasse FileSystemInfo, das erlaubt Code zu schreiben, der sowohl mit Dateien als auch mit Ordnern allgemein arbeitet.
System.Object
|
System.MarshalByRefObject
|
System.IO.FileSystemInfo (abstrakte Klasse)
| |
FileInfo DirectoryInfo
Wann Instanzklassen verwenden?
- Wenn du viele Informationen zu einer Datei/einem Ordner brauchst (Größe, Änderungsdatum, Extension, Attribute usw.) und diese Daten nicht nur einmal verwendet werden.
- Wenn du alle Dateien/Ordner in einem Verzeichnis durchlaufen und mit jedem Objekt als "lebendem" Exemplar arbeiten willst.
- Zur Optimierung, wenn es wichtig ist, nicht unnötig oft zum Dateisystem zu gehen (Caching der Informationen).
- Für einen objektorientierteren Code (Backups, Mediathek, Dateimanager usw.).
Wie man eine Instanz von FileInfo oder DirectoryInfo erstellt
using System.IO;
// Erstellen eines FileInfo-Objekts für eine existierende (oder nicht-existierende!) Datei:
var fileInfo = new FileInfo("notes.txt");
// Erstellen eines DirectoryInfo-Objekts für einen Ordner:
var dirInfo = new DirectoryInfo(@"C:\Projects");
// Du kannst relative oder absolute Pfade verwenden!
Wichtiger Punkt: Das Erstellen eines FileInfo- oder DirectoryInfo-Objekts erzeugt NICHT die Datei/den Ordner im Dateisystem! Es ist nur eine Beschreibung (eine Verknüpfung).
2. Arbeiten mit FileInfo
Lass uns die wichtigsten Properties und Methoden dieser Klasse durchgehen. Hier eine Merkliste:
| Property/Method | Was liefert es? | Beispiel |
|---|---|---|
|
Der Dateiname | |
|
Vollständiger Pfad | |
|
Dateigröße in Bytes | |
|
Elternverzeichnis (DirectoryInfo) | |
|
Existiert die Datei wirklich? | |
|
Dateiendung (.txt) | |
|
Erstellungsdatum | |
|
Datum der letzten Änderung | |
|
Nur Lesbar? | |
| Methoden | ||
|
Datei kopieren | |
|
Datei löschen | |
|
Datei verschieben | |
|
Stream zum Lesen öffnen | |
|
Stream zum Schreiben öffnen | |
Beispiel: Dateiinformationen
Fügen wir ein kleines Modul hinzu, das detaillierte Informationen über eine Datei mit FileInfo abruft.
Console.WriteLine("Gib den Dateinamen ein:");
string fileName = Console.ReadLine();
var file = new FileInfo(fileName);
if (file.Exists)
{
Console.WriteLine($"Dateiname: {file.Name}");
Console.WriteLine($"Pfad: {file.FullName}");
Console.WriteLine($"Größe: {file.Length} Bytes");
Console.WriteLine($"Erweiterung: {file.Extension}");
Console.WriteLine($"Erstellungsdatum: {file.CreationTime}");
Console.WriteLine($"Letzte Änderung: {file.LastWriteTime}");
// Zusätzlich: übergeordnetes Verzeichnis anzeigen
Console.WriteLine($"Übergeordneter Ordner: {file.DirectoryName}");
}
else
{
Console.WriteLine("Datei nicht gefunden.");
}
Beachte: wir lesen nicht den Inhalt der Datei, sondern holen nur die Metainformationen.
Praxis: Datei kopieren und löschen
// ... Innerhalb der Main-Methode nach erfolgreicher Ausgabe der Dateiinformationen:
Console.WriteLine("Gib den Pfad für die Kopie ein:");
string copyPath = Console.ReadLine();
try
{
file.CopyTo(copyPath);
Console.WriteLine($"Datei erfolgreich kopiert nach {copyPath}");
}
catch (IOException ex)
{
Console.WriteLine($"Kopieren der Datei fehlgeschlagen: {ex.Message}");
}
// Jetzt die Kopie löschen
Console.WriteLine("Kopie der Datei löschen? (y/n):");
if (Console.ReadLine().Trim().ToLower() == "y")
{
var copyFile = new FileInfo(copyPath);
if (copyFile.Exists)
{
copyFile.Delete();
Console.WriteLine("Kopie gelöscht.");
}
}
3. Arbeiten mit DirectoryInfo
Schauen wir, womit uns DirectoryInfo erfreut:
| Property/Method | Was liefert es? | Beispiel |
|---|---|---|
|
Ordnername | |
|
Vollständiger Pfad | |
|
Übergeordneter Ordner (DirectoryInfo) | |
|
Existiert der Ordner? | |
|
Erstellungsdatum | |
|
Änderungsdatum | |
| Methoden | ||
|
Ordner erstellen | |
|
Ordner löschen | |
|
Array von Dateien (Array von FileInfo) | |
|
Array von Unterordnern (Array von DirectoryInfo) | |
|
Iteration über Dateien (liefert IEnumerable<FileInfo>, lazy) | |
|
Ordner verschieben | |
Beispiel: Dateien und Ordner durchlaufen
Console.WriteLine("Gib den Pfad zum Ordner ein:");
string path = Console.ReadLine();
var dir = new DirectoryInfo(path);
if (!dir.Exists)
{
Console.WriteLine("Ordner nicht gefunden!");
return;
}
Console.WriteLine("\n--- Dateien ---");
foreach (var file in dir.GetFiles())
{
Console.WriteLine($"{file.Name} ({file.Length} Bytes)");
}
Console.WriteLine("\n--- Unterordner ---");
foreach (var subDir in dir.GetDirectories())
{
Console.WriteLine(subDir.Name);
}
4. Nützliche Feinheiten
Statische Methoden vs. Instanzklassen
Wann welchen Ansatz nutzen? Wenn du eine schnelle "einmalige" Aktion machst — z.B. File.Exists(path) oder File.ReadAllText(path) — dann sind statische Methoden oft die bessere Wahl. Sie sind simpler und etwas schneller wegen geringerer Overheads.
Wenn du jedoch viele Informationen über eine Datei/einen Ordner benötigst, wiederholte Operationen darauf ausführst oder insgesamt OOP-Style code schreibst, dann sind Instanzen von FileInfo und DirectoryInfo vorzuziehen.
Interessant ist, dass beide Ansätze "unter der Haube" ähnliche Low-Level-Systemaufrufe nutzen. Instanzklassen cachen aber einige Properties (Größe, Datum, Attribute), was die Anzahl der Zugriffe aufs Dateisystem reduziert — besonders praktisch beim Durchlaufen vieler Dateien.
Ein bisschen zu Datum und Zeit
Die Properties CreationTime, LastWriteTime, LastAccessTime liefern Werte vom Typ DateTime.
Console.WriteLine($"Datei erstellt: {file.CreationTime:yyyy-MM-dd HH:mm:ss}");
Console.WriteLine($"Letzte Änderung: {file.LastWriteTime:yyyy-MM-dd HH:mm:ss}");
Wenn die Datei oder der Ordner auf der Festplatte geändert wurde, nachdem du das FileInfo- oder DirectoryInfo-Objekt erhalten hast, können die gecachten Informationen veraltet sein. Um sie zu aktualisieren, rufe file.Refresh() auf.
Tipps und praktische Hinweise
- Instanzklassen sind praktisch, wenn du eine Wrapper-Schicht um das Dateisystem baust: Backups, Mediathek, Indexer.
- Arbeiten sehr gut mit LINQ zusammen: du kannst nach Größe, Datum oder Extension filtern und Operationen auf den ausgewählten Objekten ausführen.
- Bei Massenoperationen sind EnumerateFiles() und EnumerateDirectories() meist besser als GetFiles()/GetDirectories() — Lazy-Enumeration spart Speicher und beschleunigt den Start der Verarbeitung.
Vergleich: statischer vs. instanzieller Ansatz
| Statische Methoden | Instanzklassen | |
|---|---|---|
| Syntax | |
|
| Caching | Nein | Ja |
| Viel Information | Man muss viele Methoden aufrufen | Ist im Objekt vorhanden |
| OOP-Stil | Nein | Ja |
| Massenoperationen | Unpraktisch | Bequem |
| Arbeiten mit Streams | Ja | Ja |
Aktualisieren von Informationen und Objekten
Die Objekte FileInfo/DirectoryInfo cachen Werte nach dem ersten Zugriff auf Properties. Wenn das Objekt (Datei oder Ordner) auf der Festplatte nach der Erstellung der Instanz geändert wurde, rufe die Methode .Refresh() auf, um die Informationen zu aktualisieren.
var file = new FileInfo("notes.txt");
long oldSize = file.Length;
// In der Zwischenzeit ändert jemand (oder du selbst) die Datei außerhalb des Programms
file.Refresh();
long newSize = file.Length;
Das kommt nicht sehr oft vor, aber wenn dein Programm das Dateisystem beobachtet — ist dieser Mechanismus wichtig.
5. Typische Fehler bei der Arbeit mit Instanzklassen
Irrtum: wenn ein Objekt new FileInfo("file.txt") erstellt wird, existiert die Datei bereits. Tatsächlich ist das nicht so — die Datei erscheint erst nach explizitem Schreiben oder dem Aufruf von Create().
Der Versuch, Properties einer nicht existierenden Datei abzurufen: einige Properties geben Default-Werte zurück (z.B. Größe 0), aber der Versuch, einen Lesestream zu öffnen, wirft eine Ausnahme.
Bei Ordnern ist es ähnlich: das Erstellen von DirectoryInfo garantiert nicht, dass der Ordner auf der Festplatte existiert, bis Create() aufgerufen wird oder er tatsächlich vorhanden ist.
GO TO FULL VERSION