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.
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
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.
/*
\* 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.
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
zero_x | <span style="font-size: 10;">my</span><span style="font-size: 10;">CSharp</span><span style="font-size: 10;">.de</span> - gemeinsam mehr erreichen
Für längere Zeit inaktiv.
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.
Die Zeilen kannst du leichter mit der File.ReadAllLines-Methode (String, Encoding) (System.IO) einlesen. Da kannst du dann auch mit dem Encoding rumspielen.
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...
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
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);
}
}
}
}
}