Laden...

[gelöst] StreamReader / Lesen von Textdateien - nicht darstellbare Zeichen

Erstellt von smilingbandit vor 13 Jahren Letzter Beitrag vor 13 Jahren 3.172 Views
S
smilingbandit Themenstarter:in
151 Beiträge seit 2007
vor 13 Jahren
[gelöst] StreamReader / Lesen von Textdateien - nicht darstellbare Zeichen

Hallo zusammen,

ich habe ein Projekt in dem ich INI-Dateien behandeln muss - also ganz normale Textdateien.

Die gelesenen Daten werden von mir in einen TreeView zur Anzeige gebracht. Der Wert eines gewählten Schlüssels sollen in einer Textbox darsgestellt werden (für spätere Änderungen).

Funktioniert auch so weit alles wunderbar - außer:

Das Zeichen "°" kommt in einigen Zeichenketten vor, und kann wohl nicht richtig gelesen werden. Stattdessen tauchen Fragezeichen ( also "?" ) oder diese Vierecken bzw. Balken auf. Ich habe bereits mit diversen Konvertierungen herumgetestet und hatte noch mehr Datenverlust - sprich fehlende Zeichen usw.

Ich habe auch bereits dem Streamreader Encodings mitgegeben. Das führt interessanterweise aber immer zum Absturz der ganzen Anwendung. Leider ohne irgendeine Meldung.

Hat jemand eine entsprechende Idee, was ich ausprobieren könnte oder im Idealfall, wo die Lösung verborgen liegt?

Vielen Dank schon mal!

edit: Bevor ichs vergesse: Es scheint kein Anzeigeproblem zu sein. Beim debuggen waren die Zeichenketten bereits fehlerhaft.

D
500 Beiträge seit 2007
vor 13 Jahren

Hi!

Stattdessen tauchen Fragezeichen ( also "?" ) oder diese Vierecken bzw. Balken auf

Das laesst meistens auf ein Encoding Problem schliessen.

Ich habe auch bereits dem Streamreader Encodings mitgegeben. Das führt interessanterweise aber immer zum Absturz der ganzen Anwendung. Leider ohne irgendeine Meldung.

Du sollest schon eine Fehlermeldung herausbekommen. Zumindest kannst Du einen try-catch Block um die auslesende Methode setzen, sodass der Fehler behandelt wird und es Dir moeglich ist die Exception zu analysieren.

Gruss,
Moe

2.891 Beiträge seit 2004
vor 13 Jahren

Hast du auch mal etwas Code, wo du die INI-Datei einliest? Ansonsten können wir nur Glaskugelgucken.
Ansonsten: Hast du mal Encoding.Default probiert? Das ist - entgegen mancher Annahme - nicht das standardmäßig verwendete Encoding.

S
smilingbandit Themenstarter:in
151 Beiträge seit 2007
vor 13 Jahren


/* 
\* Methode zum Lesen der INI-Datei
\* Gleichzeitig wird ein Dictionary erzeugt, das als Basis für den TreeView dient
\*/

private void ReadData()
        {

            FileStream fileStream = new FileStream(iniFilePath, FileMode.OpenOrCreate, FileAccess.Read);
            TextReader reader = new StreamReader(fileStream);

            // Testing purposes only!

            iniFileData = new Dictionary<string,Dictionary<string,string>>();
            string currSection = String.Empty;
                        
            String line;

            while ((line = reader.ReadLine()) != null)
            {
                Match matchSection = secRegex.Match(line);
                if (matchSection.Success)
                {
                    currSection = matchSection.Groups["Section"].Value as String;
                    if (!iniFileData.ContainsKey(currSection))
                    {
                        iniFileData.Add(currSection, new Dictionary<string, string>());
                    }
                }

                else
                {
                    Match matchLine = keyValRegex.Match(line);
                    if (matchLine.Success)
                    {
                        String currKey = matchLine.Groups["Key"].Value as String;
                        String value = matchLine.Groups["Value"].Value as String;

                        Dictionary<string, string> temp;
                        iniFileData.TryGetValue(currSection, out temp);

                        if (!temp.ContainsKey(currKey))
                        {
                             temp.Add(currKey, value);
                        }
                    }
                }
            }
            fileStream.Close();
        }

Hier mal der Code zum Auslesen des ganzen. Anscheinend wird keine Exeption geworfen(?). Zumindest zeigt sich mit Try-Catch das gleiche Stoppverhalten ohne Meldung.
Über die Eleganz der Lösung kann man jetzt mal streiten 😃
Die RegEx zum Prüfen sind auch recht groß, kann ich auf Wunsch aber ebenfalls Posten.
Die auskommentierten Stellen mit Encodingformaten habe ich mal der Üersichtlichkeit wegen weg gelassen.

1.044 Beiträge seit 2008
vor 13 Jahren

Hallo smilingbandit,

ohne mir den Code anzuschauen: Hier findest du eine fertige Implementierung. Dort kannst du schauen, wie es dort programmiert worden ist. Das sollte dir eigentlich helfen.

zero_x

S
smilingbandit Themenstarter:in
151 Beiträge seit 2007
vor 13 Jahren

Hallo zusammen,

inzwischen bin ich schon etwas weiter. Ich habe die Datei mal mit Hilfe des Notepad++ in verschiedene Formate konvertiert und das Encoding des Streamreaders auf Default gestellt.

Interessanter Weise klappts jetzt und auch der Reader stürzt nicht mehr ab. Allersings ist mir das noch zu unsicher für die Zukunft 😃 Also wer noch Ideen oder Erfahrungen hat...

Vielleicht hilft der Code ja noch anderen. Werde den Ausschnitt jedenfalls up to Date halten sobald ich mir sicher bin.

2.891 Beiträge seit 2004
vor 13 Jahren

Die Zeilen kannst du leichter mit der File.ReadAllLines-Methode (String, Encoding) (System.IO) einlesen. Da kannst du dann auch mit dem Encoding rumspielen.

S
smilingbandit Themenstarter:in
151 Beiträge seit 2007
vor 13 Jahren

Die Zeilen kannst du leichter mit der
>
einlesen. Da kannst du dann auch mit dem Encoding rumspielen.

Danke, werd ich gleich mal mit einer alten Datei gegenprüfen.
Ist die Herngehensweise sinnvoll? Also eine komplette Datei einzulesen. Die INIs können ja ganz schön groß werden...

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo smilingbandit,

sie werden ja wohl kaum so groß werden, wie der Hauptspeicher. Vermutlich nicht mal annähernd. Insofern spricht auch nichts dagegen. Im Gegenteil, File.ReadAllLines vereinfacht den Programmaufbau. Und darauf kommt es heute an. Nicht darauf, noch ein paar Bytes zu sparen.

herbivore

S
smilingbandit Themenstarter:in
151 Beiträge seit 2007
vor 13 Jahren

Hallo zusammen,

aus mir unbekannten Gründen funktioniert nun das Encoding reibungslos. Außerdem bin ich auf ReadAllLines umgestiegen. Ebenfalls ohne Probleme.

@Herbivore:

Da hast du recht. Zum Glück bin ich auch kein Embedded-Entwickler der darauf achten muss 😃 Allerdings muss ich danach sowieso jede Zeile einzeln mit einer RegEx prüfen, darum - dachte ich mir - kann ich sie auch einzeln lesen und dabei prüfen 😃

Für alle dies interessiert, es sieht jetzt folgendermaßen aus:


private void ReadData()
        {
            string[] readText = File.ReadAllLines(iniFilePath, Encoding.Default);
           
            // Testing purposes only!

            iniFileData = new Dictionary<string,Dictionary<string,string>>();
            string currSection = String.Empty;
           
            foreach(string line in readText)
            {
                Match matchSection = secRegex.Match(line);
                if (matchSection.Success)
                {
                    currSection = matchSection.Groups["Section"].Value as String;
                    if (!iniFileData.ContainsKey(currSection))
                    {
                        iniFileData.Add(currSection, new Dictionary<string, string>());
                    }
                }

                else
                {
                    Match matchLine = keyValRegex.Match(line);
                    if (matchLine.Success)
                    {
                        String currKey = matchLine.Groups["Key"].Value as String;
                        String value = matchLine.Groups["Value"].Value as String;

                        Dictionary<string, string> temp;
                        iniFileData.TryGetValue(currSection, out temp);

                        if (!temp.ContainsKey(currKey))
                        {
                            temp.Add(currKey, value);
                        }
                    }
                }

            }
        }