[.NET C#] Serialization in compact framework

Pagina: 1
Acties:
  • 124 views sinds 30-01-2008
  • Reageer

  • klaasopurk
  • Registratie: Februari 2004
  • Laatst online: 18-05 09:02
hoi,

google en MSDN geven geen oplossingen voor mijn probleem, of ik zoek verkeerd.
google --> alleen normale framework
MSDN --> bepaalde object in compact framework. maar voorbeelden werken met normale framework zodat de hele boel niet werkte

ik wil een aantal object Serialization op uitvoeren. echter ik loop tegen de beperking van compactf framework. ik ontdekte dat alleen nog de namespace system.xml.Serialization nog bestaat.
hierin kan nog een XmlSerializerNamespaces aangemaakt worden. echter hier kun je verder niks mee naar mijns inziens. het obejct XmlSerializer dat ik nodig heb is niet aan te maken odmat het niet bestaat.

mijn vraag is weet iemand een manier om alsnog een object binair (Serialization) weg te schrijven.

let dus wel op het gaat om het Compact Framework.
Modbreak:Kicken van een topic staan we pas toe na 24 uur :) Ik heb je kick dan ook verwijderd

[ Voor 28% gewijzigd door gorgi_19 op 02-12-2004 12:29 ]

Klaas


  • dotcode
  • Registratie: Augustus 2003
  • Laatst online: 17-05 21:04

dotcode

///\00/\\

Ik heb niet gezocht, maar ik kan me niet voor stellen dat er geen binaryserializer bestaat. Maar mocht dat zo zijn kan je toch altijd zelf een custom serializer schrijven. Dat is vaak toch handig als je wilt dat je object in een volgende versie van je prog blijft werken. Serializen met de std seriablizers is namelijk niet zo slim.

  • klaasopurk
  • Registratie: Februari 2004
  • Laatst online: 18-05 09:02
dotcode schreef op donderdag 02 december 2004 @ 17:12:
Ik heb niet gezocht, maar ik kan me niet voor stellen dat er geen binaryserializer bestaat. Maar mocht dat zo zijn kan je toch altijd zelf een custom serializer schrijven. Dat is vaak toch handig als je wilt dat je object in een volgende versie van je prog blijft werken. Serializen met de std seriablizers is namelijk niet zo slim.
heeft iemand daarvoor een opzetje. ik heb wel aanzoiets gedacht, maar heb effe geen idee hoe aan te pakken. er komen namelijk veel verschillende objecten in hoofdobject voor. deze moeten allemaal weggeschreven worden.

Klaas


  • Brainstorm
  • Registratie: November 2000
  • Laatst online: 22:20
Voor zover ik weet, is binary serialization inderdaad op het CF weggelaten. Een aantal maanden geleden heb ik om deze reden ook een custom formatter geschreven, maar je kunt ook CompactFormatter gebruiken.

[edit]
De reden dat ik toen zelf een formatter moest schrijven, was omdat er performance problemen waren met de CompactFormatter library.

[ Voor 23% gewijzigd door Brainstorm op 02-12-2004 18:08 ]

Programmer's Drinking Song: 99 little bugs in the code, 99 bugs in the code, Fix one bug, compile it again, 100 little bugs in the code. (go to start if bugs>0)


  • P_de_B
  • Registratie: Juli 2003
  • Niet online
Zelf schrijven, een minuutje googlen geeft mij bijvoorbeeld dit

Ook is er volgens mij op http://www.opennetcf.org een class die het ondersteunt, als onderdeel van het Smart Device Framework

[ Voor 16% gewijzigd door P_de_B op 02-12-2004 18:09 ]

Oops! Google Chrome could not find www.rijks%20museum.nl


  • klaasopurk
  • Registratie: Februari 2004
  • Laatst online: 18-05 09:02
NoLife schreef op donderdag 02 december 2004 @ 18:06:
Voor zover ik weet, is binary serialization inderdaad op het CF weggelaten. Een aantal maanden geleden heb ik om deze reden ook een custom formatter geschreven, maar je kunt ook CompactFormatter gebruiken.

[edit]
De reden dat ik toen zelf een formatter moest schrijven, was omdat er performance problemen waren met de CompactFormatter library.
de performance ligt voor mijn prog erg hoog. er kunnen namelijk 20.000 objecten in staan. deze moeten razendsnel worden weggeschreven in weer in gelezen. liefst binnen 2 sec. dit zal wel niet kunnen, hoewel ik een programma ken die dat wel doet op de pocket PC, maar niet binnen .NET.

wil jij als je deze code met mij wil sharen even dit melden? Eigen prive dingen mogen er wel uit. Dat ik er dan nog even aan moet rommelen is niet zo erg. Dit is niet normaal de bedoeling van dit forum om complete code te sharen. maar dit scheelt mij dan veel werk en ik heb heel veel te doen in mijn afstuderen. alvast mijn dank.

Klaas


  • klaasopurk
  • Registratie: Februari 2004
  • Laatst online: 18-05 09:02
klaasopurk schreef op donderdag 02 december 2004 @ 19:00:
[...]


de performance ligt voor mijn prog erg hoog. er kunnen namelijk 20.000 objecten in staan. deze moeten razendsnel worden weggeschreven in weer in gelezen. liefst binnen 2 sec. dit zal wel niet kunnen, hoewel ik een programma ken die dat wel doet op de pocket PC, maar niet binnen .NET.

wil jij als je deze code met mij wil sharen even dit melden? Eigen prive dingen mogen er wel uit. Dat ik er dan nog even aan moet rommelen is niet zo erg. Dit is niet normaal de bedoeling van dit forum om complete code te sharen. maar dit scheelt mij dan veel werk en ik heb heel veel te doen in mijn afstuderen. alvast mijn dank.
wil je effe reageren AUB? dan weet ik wat ik moet doen.

overigs die compactformatter werkt totaal niet en niet aan het werk te krijgen. dan nog die van http://www.opennetcf.org werkt ook niet zoals het moet.

weet iemand er nog 1 werkende? ik moet de volgende types wegschrijven
-arrays
-eigen klassen met propertys
-eigenklassen arrays
-string
-int
-bool
-verdere standaard

Klaas


  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 19-05 13:45

gorgi_19

Kruimeltjes zijn weer op :9

En dicht, ik gooi hem straks wel weer open.. :/

Ik blijf niet herhalen over kicken. Daarnaast is niemand verplicht om te reageren op jou, als hij een reactie wil geven doet hij dat vanzelf wel :) Een opmerking als
wil je effe reageren AUB? dan weet ik wat ik moet doen.
is dan ook niet nodig :)

Sowieso begint het topic veel teveel te lijken op: "Wie weet het beste standaard component voor dit en dit probleem en begint het zelf programmeren van zaken eigenlijk steeds meer op de achtergrond te raken :)

edit:

En weer open :)

[ Voor 70% gewijzigd door gorgi_19 op 03-12-2004 13:43 ]

Digitaal onderwijsmateriaal, leermateriaal voor hbo


  • Brainstorm
  • Registratie: November 2000
  • Laatst online: 22:20
Helaas kan ik de code niet met je delen, ik denk dat mijn baas dat niet erg leuk zou vinden ;) Overigens is het idee erachter vrij simpel. In plaats van door middel van Reflection tijdens runtime te bepalen hoe objecten opgebouwd zijn is ervoor gekozen om tijdens design time in de code aan te geven welke objecten op welke manier geserialized kunnen worden. De BitConverter klasse kan gebruikt worden om de primitieven (string, bool, int, etc) naar bytes om te zetten (en omgekeerd). Op deze wijze kan een object in zijn geheel omgezet worden naar een array van bytes.

Voordeel van deze methode is dat het (de)serializen tijdens runtime sneller is, nadelen zijn dat de code niet dynamisch ook voor andere type objecten werkt en dat de onderhoudbaarheid van de code erop in moet boeten. In mijn geval wogen de voordelen op tegen de nadelen :)

Programmer's Drinking Song: 99 little bugs in the code, 99 bugs in the code, Fix one bug, compile it again, 100 little bugs in the code. (go to start if bugs>0)


  • klaasopurk
  • Registratie: Februari 2004
  • Laatst online: 18-05 09:02
NoLife schreef op zaterdag 04 december 2004 @ 15:23:
Helaas kan ik de code niet met je delen, ik denk dat mijn baas dat niet erg leuk zou vinden ;) Overigens is het idee erachter vrij simpel. In plaats van door middel van Reflection tijdens runtime te bepalen hoe objecten opgebouwd zijn is ervoor gekozen om tijdens design time in de code aan te geven welke objecten op welke manier geserialized kunnen worden. De BitConverter klasse kan gebruikt worden om de primitieven (string, bool, int, etc) naar bytes om te zetten (en omgekeerd). Op deze wijze kan een object in zijn geheel omgezet worden naar een array van bytes.

Voordeel van deze methode is dat het (de)serializen tijdens runtime sneller is, nadelen zijn dat de code niet dynamisch ook voor andere type objecten werkt en dat de onderhoudbaarheid van de code erop in moet boeten. In mijn geval wogen de voordelen op tegen de nadelen :)
Als ik het dus goed begrijp kun jij dus geen eigen klassen serializen. Dit dan wel jammer, want ik werk namelijk veel met eigen klassen die moeten worden gesesialized.

evengoed bedankt voor je reactie. ik zal nog wel effe kijken naar die bitconverter. misschien kan ik er toch wel mee werken.

Klaas


  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 18-05 09:50

pjvandesande

GC.Collect(head);

Je kan toch zelf een Seriazele class maken dmv XML of iets:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public class A
{
    private string m_value;

    public string Value
    {
        get
        {
            return m_value;
        }

        set
        {
            m_value = value;
        }
    }

    public A()
    {
    }

    // Private ctor voor het Deserializen
    private A(string value)
    {
        m_value = value;
    }

    public void Serialize(string path)
    {
        XmlTextWriter writer = new XmlTextWriter(path);
        writer.WriteStartElement("A");
        writer.WriteAttribute("m_value", m_value);
        writer.WriteEndElement();
        writer.Close();
    }

    public static A Deserialize(string path)
    {
        XmlTextReader reader = new XmlTextReader(path)
        string m_value = null;

        while(reader.Read())
        {
            if(reader.NodeType != XmlNodeType.StartElement)
                continuel;
            else
            {
                if(reader.Name == "A")
                {
                    m_value = reader.ReadElement("m_value");    
                }
            }
        }

        reader.Close();

        return (m_value != null ? new A(m_value) : null);
    }
}


Trouwens, heb het zo even in Notepad getypt, dus zou niet weten of de code ook echt werkt. Maar het is iig een idee dat jezelf zeker kan gebruiken.

[ Voor 8% gewijzigd door pjvandesande op 06-12-2004 10:25 ]


  • klaasopurk
  • Registratie: Februari 2004
  • Laatst online: 18-05 09:02
hallo allemaal

Het serializen is werkend! _/-\o_

Ik heb het via XMLwriter gedaan op ongeveer de manier van opennetCF.org . dat lijkt op de vorige post.

mijn serializer kan nu ook arrays aan. dat kon die van opennetcf niet. overigs die van opencfnet werkt bij nog een aantal dingen niet.

echter arrays terug krijgen is moelijk. In de XML staat <klasse[]><var1>value</var1><var2>value</var2><var1>value</var1><var2>value</var2></klasse[]>

Het stukje <var1>value</var1><var2>value</var2> gebeurd net zolang totdat er een einde de klasse[] komt.

echter het terughalen is een probleem. dan gebeurd er namelijk de volgende aanroep om de instantie klasse[] weer te maken

object o = t.Assembly.CreateInstance(t.FullName,true);

maar daar loopt ie op vast omdat er geen constructor klasse[] bestaat.

heeft iemand een idee hoe je dat kan omzeilen. of had ik de xml <array>....</array> moet schrijven en dat aan het eind casten naar klasse[] ?

Klaas


  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 18-05 09:50

pjvandesande

GC.Collect(head);

Wat is je code, waar lees je het mee in? Je kan toch gewoon zo iets doen:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
ArrayList tempArrayList = new ArrayList();

while(reader.Read)
{
   if(reader.NodeType == XmlNodeType.EndElement && reader.Name.ToLower() == "klasse[]")
   {
      break;
   }
   
   tempArrayList.Add(reader.ReadInnerXml());
}

return (MyArray[])tempArrayList.ToArray(typeoff(MyArray);

  • klaasopurk
  • Registratie: Februari 2004
  • Laatst online: 18-05 09:02
Mijn code ziet er als volgt uit schrik niet:

ik heb gelijk alle code gepost wat betrekking heeft op deserialize.

public object DeserializeGraph(XmlTextReader r, Type t)
{
object o = t.Assembly.CreateInstance(t.FullName);
Bij deze regel kun je de code vinden die mis gaat.

Ik hoop dat je er wijs uit kunt worden.

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
        public object Deserialize(XmlTextReader xmlReader, Type type) 
        {
            object obj;
            xmlReader.MoveToContent();
            obj = DeserializeGraph(xmlReader, type);
            return obj;
        }

        public object DeserializeGraph(XmlTextReader r, Type t) 
        {
            object o = t.Assembly.CreateInstance(t.FullName);
            string InstanceName = r.Name;
            int i = 0;

            if(o.GetType().BaseType == typeof(System.Collections.CollectionBase) || o.GetType().BaseType == typeof(System.Array))
            {
                o = DeserializeCollection(r, t);
            }

            PropertyInfo[] properties = o.GetType().GetProperties(BindingFlags.Public|BindingFlags.Instance);
            
            #region Handle XmlRoot attributes
            if(r.HasAttributes) 
            {
                while(r.MoveToNextAttribute() && i < properties.Length) 
                {
                    object[] butes = properties[i].GetCustomAttributes(false);
                    object bute = null;
                    if(butes.Length > 0) 
                    { // 16/06/2004: RHM made this into a block because bute is not always nonnull
                        bute = butes[0];

                        PropertyInfo property = null;

                        if(r.Name == (bute as XmlAttributeAttribute).AttributeName) 
                        {
                            property = properties[i];
                        }
                        else 
                        {
                            property = t.GetProperty(r.Name);
                        }
                        if(property.PropertyType.Name == "String") 
                        {
                            // We have a string
                            r.ReadAttributeValue();
                            string s = r.Value;
                            if(property.CanWrite)
                                property.SetValue(o, s, null);
                        }
                        i++;
                    }
                }
            }
            #endregion

            while(r.Read() && i < properties.Length) 
            {
                if((r.Name == InstanceName) && (r.NodeType == XmlNodeType.EndElement)) 
                {
                    break;
                }

                object[] attribs = properties[i].GetCustomAttributes(false);
                object attrib = null;

                if(attribs.Length > 0)
                    attrib = attribs[0];        
    
                if(r.HasAttributes) 
                {
                    r.MoveToFirstAttribute();
                    while(r.HasAttributes) 
                    {
                        PropertyInfo property = null;

                        if(r.Name == (attrib as XmlAttributeAttribute).AttributeName) 
                        {
                            property = properties[i];
                        }
                        else 
                        {
                            property = t.GetProperty(r.Name);
                        }

                        if(property.PropertyType.Name == "String") 
                        {
                            // We have a string
                            r.ReadAttributeValue();
                            string s = r.Value;
                            if(property.CanWrite)
                                property.SetValue(o, s, null);
                        }
                        i++;
                    }
                }
                else if((r.NodeType == XmlNodeType.Element)) 
                {
                    
                    if(r.IsEmptyElement) 
                    {
                        i++;
                        continue;
                    }

                    PropertyInfo property = null;                   
                    if(attrib == null) 
                    {
                        property = t.GetProperty(r.Name);
                        if(property == null)
                            continue;
                    }
                    else 
                    {
                        if(attrib.GetType() == typeof(XmlElementAttribute))
                        {
                            if(r.Name == (attrib as XmlElementAttribute).ElementName)
                            {
                                property = properties[i];   i++;
                            }
                            else
                                continue;
                        }
                        else if(attrib.GetType() == typeof(XmlAttributeAttribute))
                        {
                            if(r.Name == (attrib as XmlAttributeAttribute).AttributeName)
                            {
                                property = properties[i];   i++;
                            }
                            else
                                continue;
                        }
                        else if(attrib.GetType() == typeof(XmlRootAttribute))
                        {
                            if(r.Name == (attrib as XmlRootAttribute).ElementName)
                            {
                                property = properties[i];   i++;
                            }
                            else
                                continue;
                        }
                    }
                                        
                    if(property.PropertyType.BaseType == typeof(System.Collections.CollectionBase)) 
                    {
                        // We have a collection
                        property.SetValue(o, DeserializeCollection(r, property.PropertyType),null);
                    }
                    else if(property.PropertyType.Name == "String") 
                    {
                        // We have a string
                        r.Read();
                        string s = r.Value;
                        if(property.CanWrite)
                            property.SetValue(o, s, null);
                    }
                    else if(property.PropertyType.IsValueType) 
                    {
                        // We have a value type
                        object oVal = null;
                        if ( typeof(IConvertible).IsAssignableFrom(property.PropertyType) )
                        {
                            r.Read();
                            string s = r.Value;
                            if ( property.PropertyType.IsEnum )
                            {
                                try 
                                { 
                                    oVal = Enum.ToObject(property.PropertyType, Convert.ToInt32(s));
                                } 
                                catch(InvalidCastException) 
                                {
                                }
                            }
                            else
                            {

                                try { oVal = Convert.ChangeType(s, property.PropertyType, null); } 
                                catch(InvalidCastException) 
                                {
                                    try { oVal = Convert.ChangeType(s, property.PropertyType.BaseType, null); }
                                    catch(InvalidCastException) { continue; }
                                }
                            }
                        }
                        else if ( !property.PropertyType.IsPrimitive )
                        {
                            oVal = DeserializeGraph(r, property.PropertyType);
                        }
                        if ( oVal != null )
                            property.SetValue(o, oVal, null);
                    }
                    else if(t.Assembly.GetType(property.PropertyType.FullName, false) != null) 
                    {
                        // We have a type in the current assembly. Recurse.
                        object val = DeserializeGraph(r, property.PropertyType);                        
                        property.SetValue(o,val, null);
                    }
                    else 
                    {
                        throw new NotSupportedException("Cannot deserialize to " + property.PropertyType.FullName + ".");
                    }
                }
                else if(r.NodeType == XmlNodeType.Text)
                {
                    PropertyInfo property = properties[i];
                    i++;

                    if(property.PropertyType.Name == "String") 
                    {
                        // We have a string
                        //r.Read();
                        string s = r.Value;
                        if(property.CanWrite)
                            property.SetValue(o, s, null);
                    }
                }
            }
            return o;
        }

        private MethodInfo GetMethod(string MethodName, Type t) 
        {
            MethodInfo[] methods = t.GetMethods();
            MethodInfo m = null;

            foreach(MethodInfo method in methods) 
            {
                if(method.Name == MethodName) 
                {
                    m = method;
                    break;
                }
            }

            if(m == null)
                throw new NotSupportedException("Type " + t.FullName + " does not have a " + MethodName + " method.");

            return m;
        }

        private object DeserializeCollection(XmlTextReader r, Type t) 
        {
            object o = t.Assembly.CreateInstance(t.FullName);

            string InstanceName = r.Name;

            MethodInfo addToColl = GetMethod("Add",t);
            //while(r.Read()) 
            {
                if((r.NodeType == XmlNodeType.EndElement) && (r.Name == InstanceName)) 
                {
                    //break;
                    return o;
                }

                if(r.NodeType == XmlNodeType.Element) 
                {
                    string typeName = r.Name;

                    //string namePrefix = t.FullName.Replace(t.FullName, "");
                    //Type childType = t.Assembly.GetType(t.FullName + "." + r.Name,true);
                    Type childType = addToColl.GetParameters()[0].ParameterType;

                    object child = DeserializeGraph(r,childType);
                    object[] args = { child };
                    addToColl.Invoke(o,args);
                }
            }
            return o;
        }
    }

Klaas

Pagina: 1