MonoTouch/Mono for Android: Windows-1252 kodierte Texte lesen und schreiben

Eines der am nervigsten Themen mit denen man sich beim schreiben von Software rumschlagen muss ist aus meiner Sicht das Thema Encoding. Ich weiß nicht mehr wann ich das erste mal so richtig mit den Problemen konfrontiert wurde, aber es ist gefühlt eine halbe Ewigkeit. Dank Unicode und Co. werden die Probleme bei neuer Software zwar weniger, aber es kommt immer wieder die Situation in denen man Daten einlesen muss welche nicht entsprechend kodiert sind.

Als .NET Entwickler hat man durch die Klasse System.Text.Encoding allerdings eine ganz gute Waffe in der Hand um mit den verschiedenen Kodierungen umzugehen. Die Sache wird aber dann wieder “interessanter” wenn verschiedene Plattformen wie z.B. MonoTouch oder Mono for Android  im Spiel sind.

In meinem Fall muss ich Daten verarbeiten die mit einem Delphi Programm erzeugt werden. Da der Quellcode der Software vorhanden ist konnte ich sehen, dass die Daten mit der Standard Windows Codepage geschrieben werden (und da die Software nur im deutschsprachigen Raum verwendet wird kann man Windows-1252 Westeuropäisch als gegeben nehmen). Für den neuen .NET Code bin ich also ganz naiv davon ausgegangen das ich mit System.Text.Encoding.Default zum Ziel komme. Das war anfangs auch der Fall. Da die Delphi Software auch immer das Default Encoding verwendet kam es nie zu Problemen.

Das Problem

Jetzt soll der .NET Code aber auch auf Plattformen wie iOS und Android laufen. Ist ja danke MonoTouch und Mono for Android kein Problem. Nur leider unterscheidet sich das Default-Encoding dieser Plattformen von dem von Windows. Auf beiden wird UTF-8 verwendet:

MonoTouch

UTF-8 Encoding von MonoTouch

Mono for Android

mono4android

Werden die Daten nun mit dem Default-Encoding verarbeitet, dann klappt das bei einigen Zeichen noch ganz gut, aber spätestens wenn Steuerzeichen ins Spiel kommen geht das ganze schief.

Die Lösung

Die Lösung für dieses Problem ist eigentlich ganz einfach: Man besorgt sich das richtige Encoding. In meinem Fall Windows-1252 Westeuropäisch. Das geht unter .NET/Mono ganz einfach mit folgendem Einzeiler:

var encoding = Encoding.GetEncoding(1252);

Wenn man dieses Encoding jetzt an alle Lese und Schreib Methoden übergibt, dann klappt es auch wieder mit den Steuerzeichen.

   1: var encoding = Encoding.GetEncoding(1252);
   2:  
   3: File.ReadAllText(@"C:\Temp\text.txt", encoding);
   4:  
   5: File.WriteAllText(@"C:\Temp\text.txt", "content",encoding);
   6:  
   7: var sr = new StreamReader(@"C:\Temp\text.txt", encoding);
   8:  
   9: var sw = new StreamWriter(new MemoryStream(), encoding);

Ein weiteres Problem


Das Ganze hat dann unter Mono for Android auch gleich funktioniert (zumindest sah es so aus) und ich war mir sicher das es unter MonoTouch auch so sein wird. Hier wurde ich aber gleich eines besseren belehrt:


Exception MT



Die Codepage wurde nicht gefunden Trauriges Smiley


Nach ein bisschen suchen in den Projekteinstellungen und bei Google bin ich auf folgende Settings-Page gestoßen:


monotouch_settings




Hier kann man angeben welche Encodings mit in den Build integriert werden sollen. Diese werden nur bei explizit integriert um die Anwendung kleiner zu halten. Eine Liste mit den Encodings gibt es bei Xamarin: http://docs.xamarin.com/ios/advanced_topics/internationalization


Mono for Android schlägt zurück


Wie oben schon geschrieben sah es bei Mono for Android leider nur so aus, als ob es ohne Probleme funktioniert. Ich habe das ganze leider nur im Debug Build getestet. Und hier schlägt eine Eigenart von Mono for Android zu. Bei Debug Builds wird die Shared Runtime von Mono for Android verwendet. In dieser sind alle Encodings integriert. Bei Release Builds hingegen wird die Mono Runtime mit der App in das Package gelinkt. Und hier gilt nun das selbe wie bei MonoTouch: Die verfügbaren Encodings müssen explizit hinzugefügt werden.


Visual Studio


M4A Win


MonoDevelop


M4A Mac


Fazit


Nach der ganzen Aktion weiß ich wieder warum ich dieses T-Shirt besitze.
Grundsätzlich muss ich sagen, dass der Umgang mit verschiedenen Zeichenkodierungen für mich noch nie so komfortabel wie mit .NET war. Das ganze aber mal wieder “interessant” geworden ist, als MonoTouch bzw. Mono for Android mit gespielt haben. Das soll keine Kritik an Xamarin sein, da ihr vorgehen hier vollkommen legitim ist um die Größe der Anwendung zu reduzieren.


Ansonsten empfehle ich noch jedem Entwickler diesen Blogeintrag von Joel Spolsky zu lesen:


The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)

Kommentare

Beliebte Posts aus diesem Blog

Darstellung von WPF Anwendungen

Erste Schritte beim Entwickeln eines Outlook 2010 Add-ins

Monotouch - Eigene Views im Interface Builder verwenden