Laden...

BinaryFormatter mit Umlaute (ÄÜÖß)

Erstellt von caldicot vor 13 Jahren Letzter Beitrag vor 13 Jahren 3.922 Views
C
caldicot Themenstarter:in
51 Beiträge seit 2010
vor 13 Jahren
BinaryFormatter mit Umlaute (ÄÜÖß)

Hi,

ich versuche eine Klasse mit dem BinaryFormatter zu serialisieren.
Das funktioniert auch grundsätzlich.

In der Klasse habe ich einen Konstuktor zur Deserialisierung angelegt:


public Status(SerializationInfo info, StreamingContext ctxt)

und eine Methode zur Serialisierung:


public void GetObjectData(SerializationInfo info, StreamingContext ctxt)

Hier der Code der Serialisierungs-Methode:

        
public void bool serialize(string file, Object obj)
{
FileStream stream = new FileStream(file, FileMode.Create);
BinaryFormatter bFormatter = new BinaryFormatter();
bFormatter.Serialize(stream, obj);
stream.Close();
}

Dabei gehen aber Umlaute der String-Attribute der Klasse verloren.
Ich habe niergends einen Hinweis gefunden, wie man sowas lösen könnte.

Den XMLSerializer will ich eigtl. nicht hernehmen, da die Klasse immutabel sein soll und ich - wenn ich das richtig verstanden habe - Getter und Setter für alle serialisierbaren Attribute und einen Default-Konstuktor für die Klasse benötige.
In dem Konstuktor werden die Werte der Attribute gesetzt und deswegen will ich keinen Default-Konstruktor zulassen.

Gibt es wirklich keine andere Lösung?
Muss ich hier die XMLSerializer hernehmen.

Vielen Dank
caldi

916 Beiträge seit 2008
vor 13 Jahren

Hallo caldicot,

schau dir mal die das System.Text.Encoding Enum an. M. E. müsste UTF-8 -Encoding Umlaute behandeln.

Again what learned...

C
caldicot Themenstarter:in
51 Beiträge seit 2010
vor 13 Jahren

Hi,

danke für eine Antwort.
Allerdings komm ich trotzdem nicht so recht weiter.

Wo müsste ich denn das Encoding ändern?
Ich dachte die Strings in C# wären alle Unicode?
Und dem BinaryFormatter kann ich keine Kodierung mitgeben?

Könntest du bitte etwas genauer erklären was du meinst?

Danke
caldi

916 Beiträge seit 2008
vor 13 Jahren

Siehe dazu die MSDN. Den Filestream kann man ein Encoding mitgeben.

Again what learned...

916 Beiträge seit 2008
vor 13 Jahren

Mal ne andere Frage, du sagst es gehen die Umlaute verloren, gehen die wirklich schon beim Serialisieren verloren, oder erst beim lesen?

Again what learned...

C
caldicot Themenstarter:in
51 Beiträge seit 2010
vor 13 Jahren

Hi,

sorry ich steh grad aufm Schlauch.

Ich seh bei MSDN niergends, dass der FileStream eine Kodierung annimt. Nur der StreamWriter, den ich aber nicht hernehme, weil ich ja das Objekt mit dem BinaryFormatter serialisieren und ins File schreiben will.

Sorry, ich versteh grad überhaupt nix ?(

Danke
caldi

C
caldicot Themenstarter:in
51 Beiträge seit 2010
vor 13 Jahren

Hi,

ich bin mir nicht 100% sicher wo die Umlaute verloren gehen.
Wenn ich serialisiert habe und mir das File mit Notepad++ anschaue, dann kann er hier keine Umlaute darstellen.

Jetzt kann natürlich auch Notepad++ falsch lesen.
Ich nehme an, dass das schon beim Schreiben passiert beim BinaryFormatter.

Wie könnte ich denn das rauskriegen, wann das passiert?
Im Debug habe ich nicht gesehen, dass ich einen Stream-Inhalt "anschauen" kann.

EDIT:
Hier meine deserialize-Methode


        public static T deserialize<T>(string file)
        {
            if (!File.Exists(file))
            {
                throw new FileNotFoundException();
            }

            T obj;
            Stream stream = File.Open(file, FileMode.Open, FileAccess.Read);
            BinaryFormatter bFormatter = new BinaryFormatter();
            obj = (T)bFormatter.Deserialize(stream);
            stream.Close();
            return obj;
        }

Danke für Deine Hilfe und sorry für die dummen Fragen 😃
caldi

5.658 Beiträge seit 2006
vor 13 Jahren

Kommt deine Frage daher, weil du die Umlaute im Notepad nicht angezeigt werden, oder weil du Probleme beim Deserialisieren hast?

Strings werden als UTF-8 dargestellt und vom Serializer auch so in den Stream geschríeben. Wenn du im Texteditor UTF-8 als Encoding einstellst, müßten die Strings korrekt angezeigt werden, aber du darfst dabei nicht vergessen, daß es sich um Binärdaten handelt, keinen Text!

Weeks of programming can save you hours of planning

C
caldicot Themenstarter:in
51 Beiträge seit 2010
vor 13 Jahren

Nach meiner Deserialisierung sind die Umlaute komische Zeichen.
Ich habe aber nichts an der Kodierung geändert oder ähnliches.
Ich rufe die oben gepostete Methoden auf und nach der Deserialisiserung sind eben die Umlaute weg.

6.862 Beiträge seit 2003
vor 13 Jahren

Die Serialisierung macht da nichts mit der Kodierung. Wie sieht denn der Konstruktor und die GetObjectData Methode aus?

Baka wa shinanakya naoranai.

Mein XING Profil.

3.170 Beiträge seit 2006
vor 13 Jahren

Hallo,

der BinaryFormatter ist nicht dafür verantwortlich, und man braucht auch nichts umkodiern:

  static class Program
  {
    [Serializable]
    public class Test 
    {
      string testStr;
      public string TestStr 
      {
        get
        {
          return testStr;
        }
        set 
        {
          testStr = value;
        }
      }
    }
    [STAThread()]
    static void Main(string[] args)
    {
      Test test = new Test();
      test.TestStr = "äöüßabcd";

      BinaryFormatter bf = new BinaryFormatter();

      using (FileStream fs = File.Create(@"c:\temp\testfile.test")) 
      {
        bf.Serialize(fs, test);
        fs.Close();
      };

      using (FileStream fs = File.Open(@"c:\temp\testfile.test",FileMode.Open))
      {
        Test test2 = (Test)bf.Deserialize(fs);
        fs.Close();
        Console.WriteLine(test2.TestStr);
      }

      Console.Read();
    }
  }

Es wird ein Objekt erstellt, eine String-Property zugewiesen, das Objekt wird in einen FileStream serialisiert.
Dann wird in ein neues Objekt deserialisiert und die String-Property ausgegeben, und alles passt.

Die entstehende Datei ist (da binär) für einen Texteditor unbrauchbar.
Ich vermute den Fehler auch in den von talla nachgefragten Methoden.

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

C
caldicot Themenstarter:in
51 Beiträge seit 2010
vor 13 Jahren

Hi,

hier meine Methoden zur Serialisiserung:

Konstuktor:


        public Status(SerializationInfo info, StreamingContext ctxt)
        {
            this.m_kennung = (string)info.GetValue("kennung", typeof(string));
            this.m_name = info.GetValue("name", typeof(string));
            this.m_status = (string)info.GetValue("status", typeof(string));
            this.m_farbe = (Color)info.GetValue("farbe", typeof(Color));
            this.m_isMine = proofMine();
            this.m_zeit = (DateTime)info.GetValue("zeit", typeof(DateTime));
        }

Hat er hier ein Problem mit dem Cast?
Ist info.GetString() besser?

GetObjectData:


        public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
        {
            info.AddValue("kennung", this.m_kennung);
            info.AddValue("name",  this.m_name);
            info.AddValue("status", this.m_status);
            info.AddValue("farbe", this.m_farbe);
            info.AddValue("zeit", this.m_zeit);
        }

Danke
caldi

3.170 Beiträge seit 2006
vor 13 Jahren

Hallo,

Hat er hier ein Problem mit dem Cast? Nein. Ich kann aber auch sonst keinen Fehler erkennen 🤔

Ich habe mal meine Beispielklasse von oben ISerializable implementieren lassen und folgendes hinzugefügt:

      public Test(SerializationInfo info, StreamingContext ctxt)
      {
        this.testStr = (string)info.GetValue("testStr", typeof(string));
      }
      public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
      {
        info.AddValue("testStr", this.testStr);
      }

Die Methoden werden auch im Debugger brav angesprungen, und das Ergebnis ist das gleiche: es ist alles korrekt.
Bist Du sicher, daß Du nicht nur ein Anzeigeproblem hast, sondern tatsächlich Zeichen verbogen werden?
Geh mal mit dem Debugger in die beiden Funktionen und schau Dir in beiden die Strings an...

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

C
caldicot Themenstarter:in
51 Beiträge seit 2010
vor 13 Jahren

Hallo,

ich habe mein Bug gefunden.
Es hatte NICHTS mit der Serialisierung zu tun 👅

Ich lese aus einer CSV die Namen aus.
Die CSV war ANSI Codiert, ich habe aber UTF8 gelesen eben um Umlaute zu erkennen.

Jetzt habe ich die CSV UTF8 kodiert und siehe da: Jetzt funktionieren auch Umlaute vor und nach der Serialisierung bzw. Deserialisiserung 8)

Sorry, da war ich völlig auf der falschen Fährte 🙂

Vielen Dank für Eure Hilfe
caldi

X
1.177 Beiträge seit 2006
vor 13 Jahren

*hust* Debugger hust

Herr, schmeiss Hirn vom Himmel - Autsch!

Die Erfahrung zeigt immer wieder, dass viele Probleme sich in Luft auslösen, wenn man sich den nötigen Abstand bzw. Schlaf gönnt.