/// <summary> /// Gibt den Inhalt einer /// unformatierten Textdatei aus. /// </summary> /// <remarks>Die Datei muss "Wörter.txt" heißen /// und im Anwendungsverzeichnis liegen.</remarks> public void ZeigeAbweisen() { Algorithmus.Ausgeben("ZeigeAbweisen startet...", debug: true); Algorithmus.Ausgeben($"Startverzeichnis: {this.Anwendungsverzeichnis}", AusgabeModus.Debug); //Zum Testen vom eigenen Ereignis, //in 20 % der Aufrufe einen falschen Namen angeben string Dateiname = this.Zufallsgenerator.Next(100) < 80 ? "Wörter.txt" : "Wörter.Gibts.Ned"; var Pfad = System.IO.Path.Combine(this.Anwendungsverzeichnis, Dateiname); // ^-> benutzt unter Windows einen Backslash // Einen Schrägstrich in Linux /* * //Wird ein Objekt nicht sofort benötigt: * //(1) Variable für die Objektadresse * Textdatei Datei = null; * * //(2) Objekt initialisieren * Datei = new Textdatei(); */ //Es kann aber sein, dass ein Objekt sofort //benötigt wird. In diesem Fall (1) und (2) //als ein Schritt... var Datei = new Textdatei(); //(3) Objekt benutzen //Für das Ereignis LeseFehlerAufgetreten //einen Ereignisbehandler anhängen Datei.LeseFehlerAufgetreten += FehlerMelden; Datei.Pfad = Pfad; Algorithmus.Ausgeben( Datei.HoleFließtext( (int)(System.Console.WindowWidth * this.Zufallsgenerator.Next(33, 67) / 100.0f) // ^-> damit 100 nicht als Ganzzahl // interpretiert wird //-> "Typ-Bestätigung (Casten)". HoleFließtext möchte eine Ganzzahl // Die Berechnung liefert aber System.Single (float in C#) // Der Kompiler meldet, wir verlieren Genauigkeit. // Mit dem Casten wird dem Kompiler bestätigt, // dass wir das wissen (und uns hier wurscht ist, weil // keine halben Zeichen in der Konsole existieren) )); //(4) Objekt für die Vernichtung freigeben //Datei.Dis... //-> Keine Dispose() Methode zum Zusammenräumen Datei = null; //Wer räumt das Objekt aus dem Speicher? //=> Der Garbage Collector Algorithmus.Ausgeben("ZeigeAbweisen beendet.", debug: true); }
/// <summary> /// Liest den Inhalt der unformatierten /// Textdatei beschrieben im Pfad. /// </summary> protected void Lesen() { Textdatei.Ausgeben("Textdatei.Lesen startet...", AusgabeModus.Debug); try { //Datei öffnen //var Leser = new System.IO.StreamReader(this.Pfad); // sympathischer Konstruktor, hat // aber den falschen Zeichensatz, Ä, Ö, ... fehlen var Leser = new System.IO.StreamReader(this.Pfad, System.Text.Encoding.Default); // ^-> .Net kann jeden Zeichensatz darstellen // System.Text.Encoding unbedingt merken // ^-> weil der StreamReader-Konstruktor // Ausnahmen auslöst (steht im Tool-Tipp Kommentar!), // eine Fehlerbehandlung notwendig //Mit einer Abweiseschleife, solange wir nicht am Ende sind while (!Leser.EndOfStream) { this.Zeilen.Add(Leser.ReadLine().Trim()); } //Datei schließen Leser.Close(); //Es gibt Objekte, wo neben dem Dispose() auch //eine Close() Methode vorhanden ist. //In diesem Fall genügt, eine der beiden //Methoden aufzurufen //Leser.Dispose(); Leser = null; } catch (System.Exception ex) { //Was tun im Fehlerfall? //Wir sind einer Klasse und haben beim //Tippen der Klasse keine Ahnung, wer, wo //ein Objekt unserer Klasse benutzt. // //D E S H A L B : //====> NIE MIT DEM BENUTZER REDEN! // (Keine Messageboxes oder Sonstiges) // //Also, was tun? //-> eine Möglichkeit: // Weiter abstürzen //throw new System.Exception("Bessere Meldung"); //-> andere Möglichkeit: // Windows Protokolleinträge //System.Diagnostics.EventLog.WriteEntry(.... // ^-> das benötigt eine Quelle //System.Diagnostics.EventLog.CreateEventSource(.... // ^-> nur mit Adminrechten möglich //=> Der Trainer hat das aufgegeben, weil // Administratoren kein Verständig dafür haben //-> eigenes Protokoll (im Teil 2) // //=> State of the Art // //-> Lieber Objektbenutzer, kümmere dich selber um das Problem //=> Ein Ereignis auslösen this.OnLeseFehlerAufgetreten(new FehlerAufgetretenEventArgs(ex)); } Textdatei.Ausgeben("Textdatei.Lesen beendet.", AusgabeModus.Debug); }