1. Einführung
StreamWriter ist eine der wichtigsten Klassen im Namespace System.IO in .NET, die dafür gedacht ist, Textdaten bequem über einen Stream in Dateien zu schreiben.
Warum sollte man nicht direkt mit FileStream arbeiten?
FileStream arbeitet nur mit Bytes. Wenn du versuchst, einen String damit zu schreiben, musst du den Text selbst in Bytes umwandeln und dich um das Encoding kümmern (spätestens dann willst du wieder zu StreamWriter zurück).
StreamWriter nimmt dir diesen Stress ab: Du gibst ihm einen String – er schreibt die richtigen Bytes in die Datei.
Die wichtigsten Vorteile:
- Du kannst Strings schreiben, ohne an die Umwandlung in Bytes zu denken.
- Es gibt Methoden, um Text zeilenweise zu schreiben.
- Du kannst Buffering und Encoding steuern (und das lernst du gleich noch).
Ein ganz einfaches Beispiel
using System.IO;
string path = "output.txt";
using (StreamWriter writer = new StreamWriter(path))
{
writer.WriteLine("Hallo, Welt!");
writer.WriteLine("Das ist die zweite Zeile.");
}
// Nach dem Verlassen der using-Klammern gibt StreamWriter die Datei garantiert frei.
Was passiert hier?
- Die Datei wird zum Schreiben geöffnet (wenn sie nicht existiert, wird sie erstellt).
- Jede Zeile wird als eigene Zeile in die Datei geschrieben (Methode WriteLine).
- Nach dem using-Block wird die Datei automatisch geschlossen, auch wenn Fehler auftreten.
Wenn du die Datei output.txt nach dem Ausführen dieses Programms öffnest, siehst du zwei Textzeilen, genau wie erwartet.
Wichtiger Hinweis
Wenn die Datei schon existiert, wird sie komplett überschrieben! Alles, was vorher drin war, ist weg. Also Vorsicht: Speichere da keine wichtige Doktorarbeit oder die einzige Quittung für die Nebenkosten.
2. Daten in einen Stream schreiben
Die wichtigsten Methoden von StreamWriter
| Methode | Beschreibung |
|---|---|
|
Schreibt einen String ohne Zeilenumbruch |
|
Schreibt einen String mit Zeilenumbruch |
|
Schreibt den Buffer sofort in die Datei (muss man selten manuell machen) |
/ |
Schließt den Stream und gibt Ressourcen frei (macht using) |
|
Zugriff auf den Basis-Stream (z.B. FileStream) bekommen |
Methode Write()
Schreibt Daten ohne Zeilenumbruch. Alles, was du danach schreibst, landet in derselben Zeile der Datei.
Methode WriteLine()
Schreibt Daten und fügt automatisch ein Zeilenende-Zeichen hinzu (\r\n unter Windows, \n unter Unix-Systemen).
Das ist wie Enter drücken nach jedem Schreiben.
Write() vs WriteLine(): Unterschied zeigen
using (var writer = new StreamWriter("example.txt"))
{
writer.Write("Erster ");
writer.Write("Absatz. ");
writer.WriteLine("Zeile fertig, Enter!");
writer.Write("Zweiter Absatz.");
}
Jetzt sieht example.txt ungefähr so aus:
Erster Absatz. Zeile fertig, Enter!
Zweiter Absatz.
3. Arbeiten mit Encodings
Standardmäßig wird beim Erstellen von StreamWriter ohne Parameter das Encoding UTF-8 mit BOM (Byte Order Mark) verwendet.
Das ist in der Praxis bequem und modern, aber manchmal muss man das Encoding explizit angeben – zum Beispiel für alte Programme oder importierte Daten.
Wie gibt man das Encoding an?
// Datei im Encoding Windows-1251 (Kyrillisch für alte Systeme) schreiben
using (var writer = new StreamWriter("cyrillic.txt", false, System.Text.Encoding.GetEncoding("windows-1251")))
{
writer.WriteLine("Hallo, kyrillische Welt!");
}
Wichtiger Punkt:
Das Encoding muss vom System unterstützt werden. Wenn du unsicher bist – nimm UTF-8.
4. Zusätzliche Konstruktor-Parameter
Wir schauen mal in die Innereien von StreamWriter:
public StreamWriter(
string path, // Pfad zur Datei
bool append = false, // ans Ende anhängen?
Encoding encoding = null, // Encoding
int bufferSize = 1024 // Buffer-Größe in Bytes
)
- append – wenn false (Standard), wird die Datei überschrieben. Wenn true, werden neue Einträge ans Ende angehängt.
- encoding – das verwendete Encoding.
- bufferSize – Größe des internen Buffers für schnellere Arbeit mit großen Datenmengen.
Beispiel: In dieselbe Datei anhängen
// Die Datei wird ergänzt, nicht überschrieben
using (var writer = new StreamWriter("log.txt", append: true))
{
writer.WriteLine(DateTime.Now + " -- Neues Ereignis");
}
5. Nützliche Details
Was passiert beim Anhängen und Überschreiben
| Modus | Was macht das? | Ergebnis in der Datei |
|---|---|---|
| append: false | Überschreibt alles komplett | Alte Daten werden gelöscht |
| append: true | Hängt neue Zeilen ans Ende | Alte Zeilen bleiben erhalten |
Tipp: Der Anhänge-Modus (append: true) ist super für Logging, wenn du eine Ereignishistorie behalten willst.
StreamWriter und große Datenmengen
- StreamWriter puffert das Schreiben: Die echten Daten landen etwas später in der Datei, als du WriteLine aufrufst. Aber nach dem Schließen des Streams (oder Flush()) ist alles garantiert auf der Platte.
- Schreiben mit WriteLine ist super effizient für zeilenweisen Output. Für komplexe Formate (JSON, CSV oder XML) nimm lieber passende Libraries oder achte auf korrektes Escaping von Sonderzeichen (z.B. Kommas oder Anführungszeichen).
Wie man das Schreiben richtig beendet und Ressourcen freigibt
Der richtige Weg: Immer using verwenden!
So stellst du sicher, dass die Datei geschlossen wird, auch wenn eine Exception passiert (z.B. wenn die Festplatte plötzlich "voll" ist oder eine andere App die Datei blockiert).
flowchart TD
A[StreamWriter erstellen] --> B[Mit Datei arbeiten]
B --> C{Exception?}
C -- Ja --> D[Dispose wird aufgerufen]
C -- Nein --> D
D --> E[Datei garantiert geschlossen]
6. Praktische Beispiele
Angenommen, wir haben im Kurs ein Mini-Programm zur Buchverwaltung. Wir fügen die Funktion hinzu, neue Bücher in eine Datei zu schreiben.
Beispiel: Ein neues Buch in eine eigene Datei speichern
using System;
using System.IO;
class Program
{
static void Main()
{
Console.WriteLine("Gib den Buchtitel ein:");
string bookTitle = Console.ReadLine();
Console.WriteLine("Gib den Autor ein:");
string author = Console.ReadLine();
string path = "books.txt";
using (var writer = new StreamWriter(path, append: true))
{
writer.WriteLine($"{bookTitle};{author}");
// CSV-Format: Jede Zeile – ein Buch, getrennt mit Semikolon
}
Console.WriteLine("Buch wurde in der Datei gespeichert!");
}
}
Probier mal, mehrere Bücher hintereinander hinzuzufügen. In der Datei books.txt werden die Zeilen ergänzt, ohne die alten zu löschen. Das ist praktisch für Logs oder Journale – zum Beispiel für dein zukünftiges Audit-System, wenn du mal Enterprise-Entwickler wirst.
7. Wie man typische Fehler beim Schreiben in Dateien vermeidet
Die meisten Anfänger stolpern über diese Probleme:
Datei nicht geschlossen und von einem anderen Prozess gesperrt. Grund: using vergessen.
Viele Zeilen geschrieben, aber die Datei bleibt leer: Flush() oder Stream schließen vergessen (mit using passiert das automatisch).
Datei versehentlich überschrieben statt angehängt – append: true vergessen.
Encoding-Probleme: Datei sieht in Notepad wie Kauderwelsch aus – falsches Encoding gewählt oder das andere Programm unterstützt UTF-8 nicht.
Exceptions wie UnauthorizedAccessException oder DirectoryNotFoundException: Das Programm versucht, die Datei an einem Ort zu speichern, wo es keine Rechte hat oder der Ordner nicht existiert. Pfad und Zugriffsrechte prüfen.
Fehler "file is used by another process": Du hast die Datei zum Schreiben geöffnet, aber nicht geschlossen, oder jemand anders versucht gleichzeitig, darauf zu schreiben.
GO TO FULL VERSION