Eine Datei mit C# lesen

Mit der Fähigkeit Dateien mit seiner Anwendung zu lesen, ermöglicht das einem ganz neue möglichkeiten. Man kann entweder Ausgaben von anderen Programmen weiter verarbeiten, die nicht in C# geschrieben wurden. Oder man kann auch Daten die man selbst geschrieben hat wieder laden. Oder man kann könnte Dateien als "Konfigurationsdateien" benutzen um den Usern eine Möglichkeit zu geben in den Programmablauf einzugreifen.
Auf jeden Fall findet man immer und immer wieder Szenarien und Möglichkeiten wie man sich das einlesen von Dateien zu nutze machen kann. Wie das nun mit C# funktioniert, möchte ich hier kurz erklären.

FileAccess und FileMode

Bevor wir Anfangen sollten wir noch kurz zwei Begrifflichkeiten klären. Um Dateien zu öffnen benötigen wir zwei Parameter. Richt geraten. Zum einen den FileMode: der dem Betriebssystem mitteilt wie die Datei zu öffnen ist. Und zum anderen den FileAccess, mit dem wir sagen, was wir mit der Datei machen möchten. In unserem Fall nehmen wir FileMode.Open und FileAccess.Read.

Mit FileMode.Open sagen wir dem OS das wir eine vorhandene Datei öffnen möchten und mit FileAccess.Read, das wir diese Datei einfach nur lesen wollen.

Erstellen des FileStream

Wie beim schreiben von Dateien auch, gibt es auch beim lesen von Dateien immer mehr als einen Weg der zum Ziel führt.

  • Die statische Open Methode von File
    1. FileStream stream = File.Open("demo.txt", FileMode.Open, FileAccess.Read);
  • Den FileStrem Konstrucktor
    1. FileStream stream = new FileStream("demo.txt", FileMode.Open, FileAccess.Read);
  • Die Open Methode von FileInfo
    1. FileInfo info = new FileInfo("demo.txt");
    2. FileStream stream = fileInfo.Open(FileMode.Open, FileAccess.Read);
  • Alternativ kann man aber auch auf dem StreamReader setzen.
    1. StreamReader reader = new StreamReader("demo.txt");

Alle vier der oben genannten Methoden haben das selbe Ziel. Und zwar die Datei "demo.txt" im lese Modus zu öffnen. Wenn der Pfad oder die Datei nicht existieren, haben alle Methoden eins gemeinsam. Sie werfen einen Fehler. Das kann von eine System.IO.IOException bis zu einer Syste.IO.FileNotFoundException alles sein. Daher sollte man immer vorher prüfen ob die Datei existiert, und ob man die nötigen Berechtigungen zum lesen der Datei hat, die man öffnen möchte.

Ich perönlich mag die erste Variante, da diese einfach und schnell zu benutzen ist. Allerdings kann das bei sehr großen Dateien zu einigen Problemen führen. Um den Speicher nicht sinnlos mit dem Inhalt der Datei zu füllen nutze ich für große Dateien den StreamReader. Allerdings hat die FileInfo Variante auch Ihre Vorzüge. z.B. Kann ich direkt nach der Initialisierung des FileInfo Objektes nachfragen ob die Datei denn wirklich existiert...

  1. FileInfo info = new FileInfo("demo.txt");
  2. if (info.Exists) // nachfragen ob die Datei wirklich existiert
  3. {
  4. FileStream stream = info.Open(FileMode.Open, FileAccess.Read); // lesen der Datei in einen Stream
  5. }
  6. else
  7. {
  8. Console.Write("Die Datei demo.txt wurde nicht gefunden.");
  9. }

Aber die Wahl bleibt ja jedem selbst überlassen. :-)

Lesen von Text Dateien

Nun gehen wir noch ein wenig mehr ins Detail. Angenommen wir wollen eine einfache Text Datei lesen, und diese auf der Konsole ausgeben.
Ein Beispiel wie man das realisieren kann zeigt der folgender Code aus einer Konsolen Anwendung.

  1. public static void ReadFileAndPrintToConsole()
  2. {
  3. try
  4. {
  5. var fileInfo = new FileInfo("demo.txt");
  6.  
  7. // Prüfen ob die Datei existiert
  8. if (fileInfo.Exists)
  9. {
  10. // Datei in einen FileStream laden
  11. var fileStream = fileInfo.Open(FileMode.Open, FileAccess.Read);
  12.  
  13. // StreamReader initialisieren
  14. var reader = new StreamReader(fileStream);
  15.  
  16. String line;
  17.  
  18. // Lese Datei, Zeile für Zeile
  19. while ((line = reader.ReadLine()) != null)
  20. {
  21. // Ausgabe der zuletzt gelesen Zeile
  22. Console.WriteLine(line);
  23. }
  24.  
  25. reader.Close();
  26. fileStream.Close();
  27. }
  28. else
  29. {
  30. Console.WriteLine("Die Datei demo.txt wurde nicht gefunden.");
  31. }
  32. }
  33. catch (IOException ex)
  34. {
  35. Console.WriteLine(ex);
  36. }
  37. }

Der Code ist nichts sonderlich spezielles. Wo oben schon beschrieben, wird geprüft, ob die angegebene Datei "demo.txt" existiert. Wenn das der Fall ist, wird auf Basis des FileInfo Objektes, mit der Funktion Open() ein FileStream geöffnet.
Um nun diesen Stream zu lesen wird wird ein sogenannter StreamReader initialisiert, der sich die Daten aus dem Stream holt. Dieser Reader bietet nun mehrere Funktionen um genau dieses zu tun. In dem oben gezeigten Beispiel, nutzen wir die Funktion ReadLine() um die Datei Zeile für Zeile zu lesen, und diese im Anschluss auf der Konsole auszugeben.
Wenn der Reader am Ende angelangt ist, liefert ReadLine() anstatt einen String den Wert NULL zurück.
Danach räumen wir noch ein bisschen auf, schließen den Reader und den Stream, so das alle Referenzen und Zugriffe auf die Datei wieder frei gegeben werden.

Bei diesem Beispiel werden allerdings keine Dateiberechtigungen und Zugriffsbeschränkungen berücksichtigt! Weitere Informationen hierzu findest du unter "Dateiberechtigungen mit C#".

Lesen von Binären Dateien

Beim lesen und Verarbeiten von Binären Dateien, sieht es sehr ähnlich aus. Nur eben das die Daten Binär sind und es somit eine weitere Verarbeitung braucht.
Zum Beispiel kann man seine Objekt Serialisieren um diese dann in einem Binären Format zu speichern. Diese Daten können wir später wieder laden. Allerdings müssen wir diese anschließend wieder Deserialisieren um das Objekt wieder herzustellen zu können.
Doch diese ganze Funktionsweise hat nur noch wenig mit dem Lesen von Dateien zu tun.

Zum Lesen von Binaren Daten benötigen wir keinen "speziellen" Reader mehr, sondern wir holen uns die Daten direkt aus dem Stream.

  1. public static void ReadBinaryFileToArray()
  2. {
  3. try
  4. {
  5. var fileInfo = new FileInfo("demo.txt");
  6.  
  7. // Prüfen ob die Datei existiert
  8. if (fileInfo.Exists)
  9. {
  10. // Datei in einen FileStream laden
  11. var fileStream = fileInfo.Open(FileMode.Open, FileAccess.Read);
  12.  
  13. // Buffergröße festlegen
  14. var buffer = new byte[1024];
  15.  
  16. // Temporärer Speicher initialiseren
  17. var fileContent = new List<byte>();
  18.  
  19. // Lesen des Streams
  20. while((fileStream.Read(buffer, 0, buffer.Length)) != 0)
  21. {
  22. fileContent.AddRange(buffer);
  23. }
  24.  
  25. // Stream schließen
  26. fileStream.Close();
  27.  
  28. // ToDo: Weitere Verarbeitung mit den geladenen Binardaten ...
  29. }
  30. else
  31. {
  32. Console.WriteLine("Die Datei demo.txt wurde nicht gefunden.");
  33. }
  34. }
  35. catch (IOException ex)
  36. {
  37. Console.WriteLine(ex);
  38. }
  39. }

Diese Funktion ist im Grunde eine leichte Modifikation der weiter oben geschrieben Funktion ReadFileAndPrintToConsole(). Der Unterschied liegt darin, das der Inhalt der Datei nicht auf der Konsole ausgegeben wird, sondern in einem temporären Puffer von 1024 Byte gelesen und danach in eine Byte List gepeichert wird.

Auch bei diesem Beispiel werden keine Dateiberechtigungen und Zugriffsbeschränkungen berücksichtigt!

Tags: 
Kategorie: 

Neuen Kommentar schreiben