CodeGym /Kurse /C# SELF /Statische Klassen File

Statische Klassen File und Directory

C# SELF
Level 39 , Lektion 0
Verfügbar

1. Einführung

Direkt mit Streams zu arbeiten (StreamReader, StreamWriter, FileStream) ist sehr nützlich, besonders wenn du den Lese-/Schreibvorgang auf niedrigem Level kontrollieren musst: z.B. in Blöcken "nach und nach" schreiben oder große Dateien stückweise verarbeiten.

In der Praxis will man aber oft einfach nur wissen: "Existiert diese Datei?", "Datei von A nach B kopieren", "Datei löschen", "Liste aller .txt-Dateien im Ordner bekommen" usw. Für solche Aufgaben hat Microsoft zwei universelle Werkzeuge geschaffen: die statischen Klassen File und Directory. Statisch bedeutet: keine Instanz erzeugen, du rufst die Methode direkt am Klassennamen auf.

Lebensnahe Analogie

Wenn Streams du mit einem Bleistift sind, der sorgfältig jeden Buchstaben auf ein Blatt schreibt, dann sind File und Directory dein Schreibtisch mit Schubladen: du kannst schnell eine Schublade öffnen (Directory), einen Zettel herausnehmen (File.ReadAllText), den Zettel wegwerfen (File.Delete) oder sogar eine ganze Schublade aus dem Schrank ziehen und ans andere Ende des Zimmers bringen (Directory.Move). Einfache Aufgaben — einfache Methoden.

2. Die Klasse File: was sie ist und wofür sie gut ist

Die Klasse File bietet eine praktische Sammlung statischer Methoden für alle gängigen Dateioperationen.

Am häufigsten verwendete Methoden

Methode Beschreibung
File.Exists(path)
Prüft, ob eine Datei unter dem Pfad existiert
File.ReadAllText(path)
Liess die ganze Datei als Text
File.ReadAllLines(path)
Liess alle Zeilen der Datei in ein Array
File.WriteAllText(path, text)
Überschreibt die Datei und schreibt Text hinein
File.AppendAllText(path, text)
Hängt Text am Ende der Datei an
File.Copy(source, destination)
Kopiert eine Datei
File.Delete(path)
Löscht eine Datei
File.Move(source, destination)
Verschiebt oder benennt eine Datei um
File.Open/Read/Write/Create
Öffnet einen Stream für komplexe Operationen

Schnelles Beispiel: Datei prüfen und lesen

string filePath = "data.txt";

if (File.Exists(filePath))
{
    string content = File.ReadAllText(filePath);
    Console.WriteLine("Inhalt der Datei:");
    Console.WriteLine(content);
}
else
{
    Console.WriteLine("Datei nicht gefunden!");
}

Siehst du? Kein manuelles Stream-Management für den einfachen Fall!

3. Die Klasse Directory: Verzeichnisse schmerzfrei verwalten

Wenn File für einzelne Dateien ist, dann ist Directory für Ordner (Directories).

Wesentliche Aufgaben

Methode Beschreibung
Directory.Exists(path)
Prüft, ob ein Ordner existiert
Directory.CreateDirectory(path)
Erstellt einen Ordner (inkl. aller Zwischenordner)
Directory.Delete(path)
Löscht einen Ordner (optional mit Unterverzeichnissen)
Directory.GetFiles(path)
Gibt die Liste der Dateien in einem Ordner zurück
Directory.GetDirectories(path)
Gibt die Liste der Unterverzeichnisse zurück
Directory.Move(source, destination)
Verschiebt oder benennt einen Ordner um
Directory.GetCurrentDirectory()
Holt das aktuelle Arbeitsverzeichnis der Anwendung

Beispiel: Ordner erstellen und Datei dort speichern

string dirPath = "Results";
if (!Directory.Exists(dirPath))
{
    Directory.CreateDirectory(dirPath);
    Console.WriteLine("Ordner 'Results' wurde erstellt.");
}

string filePath = Path.Combine(dirPath, "summary.txt");
File.WriteAllText(filePath, "Ergebnisdaten: ...");

Console.WriteLine($"Datei {filePath} wurde geschrieben.");

4. Typische Anwendungsszenarien für File und Directory

Die Basis-Methoden wirken langweilig, wenn man sie nicht in Aktion sieht! Schauen wir, wie man diese Klassen in echten Aufgaben nutzt und erweitern unser fiktives kleines Programm (nehmen wir an, wir bauen ein einfaches todo-list System, das Ergebnis speichern wir in Dateien).

Daten in Datei speichern (alte Datei ersetzen)

// Speichere die Aufgabenliste in eine Datei
string[] todos = { "Kupiit khleb", "Pozvonit vrachu", "Sdelat domashku po C#" };
string filePath = "todo.txt";
File.WriteAllLines(filePath, todos);

Console.WriteLine("Aufgabenliste gespeichert.");

Daten aus Datei laden

// Lade Aufgaben, falls die Datei existiert
if (File.Exists(filePath))
{
    string[] loadedTodos = File.ReadAllLines(filePath);
    Console.WriteLine("Deine Aufgabenliste:");
    foreach (var task in loadedTodos)
    {
        Console.WriteLine("- " + task);
    }
}
else
{
    Console.WriteLine("Du hast noch keine Aufgabenliste.");
}

Neue Aufgabe hinzufügen (ohne Datei zu überschreiben)

string newTask = "Pogulyat s sobakoy";
File.AppendAllText(filePath, newTask + Environment.NewLine);
Console.WriteLine("Aufgabe hinzugefügt!");

Datei kopieren und Backup erstellen

string backupPath = "todo_backup.txt";
File.Copy(filePath, backupPath, overwrite: true);
Console.WriteLine("Backup der Aufgabenliste erstellt.");

Datei verschieben (oder umbenennen)

string archivePath = "todo_archive.txt";
File.Move(filePath, archivePath);
Console.WriteLine("Aufgabenliste archiviert (umbenannt).");

Datei löschen

if (File.Exists(archivePath))
{
    File.Delete(archivePath);
    Console.WriteLine("Archiv gelöscht — Speicher freigemacht!");
}

5. Arbeiten mit Ordnern: Beispiele

Erstellen einer Verzeichnis-Hierarchie

string path = Path.Combine("Reports", "2024", "June");
Directory.CreateDirectory(path);
Console.WriteLine($"Ordner {path} erstellt (inklusive Zwischenordner).");

Datei- und Ordnerliste erhalten

string dirPath = "Reports";
if (Directory.Exists(dirPath))
{
    string[] files = Directory.GetFiles(dirPath);
    Console.WriteLine("Dateien im Ordner:");
    foreach (var file in files)
    {
        Console.WriteLine(file);
    }

    string[] subDirs = Directory.GetDirectories(dirPath);
    Console.WriteLine("Unterverzeichnisse:");
    foreach (var dir in subDirs)
    {
        Console.WriteLine(dir);
    }
}

Dateien nach Maske filtern (nur txt)

string[] txtFiles = Directory.GetFiles(dirPath, "*.txt");
Console.WriteLine("Nur .txt-Dateien:");
foreach (var file in txtFiles)
{
    Console.WriteLine(file);
}

Rekursives Durchlaufen (Dateien in allen Unterordnern)

string[] allFiles = Directory.GetFiles(dirPath, "*.*", SearchOption.AllDirectories);
Console.WriteLine("Dateien in allen verschachtelten Ordnern:");
foreach (var file in allFiles)
{
    Console.WriteLine(file);
}

Verschieben und Löschen von Verzeichnissen

string from = "OldReports";
string to = "Archive/OldReports";
if (Directory.Exists(from))
{
    Directory.Move(from, to);
    Console.WriteLine($"Ordner {from} wurde nach {to} verschoben");
}

if (Directory.Exists(to))
{
    Directory.Delete(to, recursive: true); // true: alles darin löschen
    Console.WriteLine($"Ordner {to} gelöscht (inkl. Inhalt).");
}

6. Nützliche Feinheiten

Integration mit Pfaden: die Klasse Path

Beim Arbeiten mit Dateien und Ordnern muss man oft volle Pfade zusammensetzen, Verzeichnis- und Dateinamen verbinden, Erweiterungen auslesen oder ungültige Zeichen prüfen. Dafür gibt es die Hilfsklasse Path.

Beispiele

string folder = "Results";
string filename = "week1.txt";
string fullPath = Path.Combine(folder, filename); // sicheres Zusammenfügen!
Console.WriteLine(fullPath); // "Results/week1.txt" (oder "\" auf Windows)
  • Dateierweiterung bekommen: Path.GetExtension(fullPath)
  • Dateiname ohne Pfad: Path.GetFileName(fullPath)

Verwende Path.Combine statt String-Konkatenation — das ist sicherer für plattformübergreifende Anwendungen.

„Alles auf einmal“-Methoden vs. stream-basierte Varianten

Viele Methoden von File und Directory (z.B. File.ReadAllText, File.WriteAllText, Directory.GetFiles) erledigen die Arbeit "komplett": sie lesen/schreiben/lesen die Dateiliste in einem Rutsch. Das ist SEHR praktisch, aber nicht geeignet für extrem große Dateien oder Verzeichnisse, wo der Speicher erschöpft sein könnte. Bei Gigabyte-Dateien wechselst du zu Streams (StreamReader, StreamWriter, FileStream usw.) oder verarbeitest die Daten stückweise.

Wann File/Directory verwenden und wann Streams

Situation Was verwenden
Du willst prüfen, ob Datei/Ordner existiert
File.Exists, Directory.Exists
Eine kleine Datei komplett lesen/schreiben
File.ReadAllText, WriteAllText
Text an eine Datei anhängen
File.AppendAllText
Dateiliste in einem Verzeichnis bekommen
Directory.GetFiles
Datei kopieren, löschen, verschieben
File.Copy/Delete/Move
Ganzen Ordner kopieren/löschen Directory.Delete/Move/Copy (Copy — mit externer Bibliothek)
Sehr große Dateien stückweise verarbeiten Stream-Klassen (StreamReader, FileStream)

Praxisrelevanz und echte Anwendungen

  • Schnelles Laden/Speichern von Konfigurationen, Settings, JSON-/XML-Dateien.
  • Logging-Systeme (Logs auf Festplatte schreiben).
  • Einfache Backup-Utilities und Datenmigrationen.
  • Scannen von Ordnern mit Medien, Fotos, Dokumenten.
  • Benutzer-Szenarios: Templates laden, Import/Export, Reports generieren usw.

Bei Coding-Interviews kommen oft Aufgaben, die genau diese Klassen verlangen: "Implementiere eine Funktion, die die Gesamtgröße aller .txt-Dateien in einem Verzeichnis berechnet", "Erstelle ein Backup der Dateien in ein separates Verzeichnis" usw.

Visuelle Spickzettel: welches Methode wann

graph TD
    A[Was willst du tun?]
    A -->|Existenz prüfen| B[File.Exists oder Directory.Exists]
    A -->|Datei komplett lesen/schreiben| C[File.ReadAllText/WriteAllText]
    A -->|Daten an Datei anhängen| D[File.AppendAllText]
    A -->|Mit Ordnern arbeiten| E[Directory.CreateDirectory, GetFiles, GetDirectories]
    A -->|Datei kopieren/löschen/verschieben| F[File.Copy/Delete/Move]
    A -->|Ordner komplett kopieren/löschen| G[Directory.Delete/Move]

7. Besonderheiten und typische Fehler

Existenzprüfung und "Race-Condition". Selbst wenn du prüfst, ob eine Datei/ein Ordner existiert, kann zwischen dieser Prüfung und der eigentlichen Operation ein anderer Prozess die Situation ändern. Deshalb immer try-catch verwenden, auch wenn du vorher geprüft hast!

Zugriffsrechte. Wenn der Anwendung die Rechte zum Lesen/Schreiben/Löschen fehlen, werfen die Methoden eine UnauthorizedAccessException.

Pfad zu lang. Maximale Pfadlänge (meist 260 Zeichen auf älteren Windows; in .NET 9 sind die Einschränkungen gelockert, aber Vorsicht ist geboten).

Fehlerbehandlung. Methoden wie File.ReadAllText oder Directory.GetFiles verzeihen keine Fehler: wenn Datei/Ordner fehlt — wird sofort eine Ausnahme geworfen. Pack die Aufrufe in try-catch oder prüfe vorher das Vorhandensein.

Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION