Sérialiser une arraylist [Résolu]

Messages postés
498
Date d'inscription
mercredi 7 juillet 2004
Statut
Membre
Dernière intervention
13 juillet 2015
- - Dernière réponse : scoubidou944
Messages postés
728
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
19 janvier 2017
- 8 févr. 2006 à 16:23
Bonjour,



alors, je viens de découvrir la sérialisation et juste après, j'ai découvert arraylist dont je ne méttais jamais servi.



Ce que je souhaite, c'est exporter en XML toutes les instances de ma
classe. Alors j'ai pensé mettre toutes ces instances dans un arraylist,
pour ensuite faire la sérialisation de toutes ces instances.

J'ai trouvé la méthode pour sérialiser un objet. Mais apparement, cela pose plus de problème pour un arraylist.



Le but de tout ça : je veux faire du stockage en dehors de mon appli,
je me suis orienté vers XML car je pense que cela correspond à mes
besoins, plus qu'une base de données.

Disons que j'ai une classe Fichier, dont chaque occurence possède 3 ou
4 propriétés d'un fichier. (numéro, statut, et nom du matériel)



Alors en fait, je télécharge d'un boîtier électronique une liste de fichiers avec leurs caractéristiques ci dessus. Je veux stocker cette liste à l'extérieur de l'application pour la retrouver au prochain lancement de cette dernière.

J'aurais donc par exemple dans l'ordre (n°, statut, nom):

instance1 : 1,statut1,machine1

instance2 : 2,statut2,machine2

instance3 : 3,statut2,machine1



Donc 3 instances de ma classe "fichier", que je voudrais pouvoir
retrouver lors de la prochaine exécution de l'appli. (et si possible,
les remettre dans des instances de fichier lors de la désérialisation)



J'arrive donc à la question : Quels est le format à adopter pour le
fichier XML (les balises, l'ordre, etc...car je ne sais pas du tout) et
comment envoyer dans un fichier XML toutes les instances de ma classe
fichier ? Est-ce que je peux passer par un arraylist ? Ou bien il faut
faire la sérialisation instance par instance ? (j'ai essayé cette
dernière solution, mais j'ai eu une erreur qui vient du format des
balises je pense)



Voilà ce que j'ai essayé :

private void ArrayListToXML_Click(object sender, System.EventArgs e)

{

XmlSerializer serialiseur = new XmlSerializer(typeof(Fichier));

TextWriter writer = new StreamWriter("monfichier.xml");

Fichier coucou;

foreach (object o in al)

{

coucou = (Fichier)o;

serialiseur.Serialize(writer,coucou);

}

writer.Close();

}



Alors, avec une seule instance dans l'arraylist, ca marche, voici le contenu du fichier XML :



<?xml
version="1.0" encoding="utf-8" ?>





[# -] <Fichier xmlns:xsd=" http://www.w3.org/2001/XMLSchema " xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance">






<numero>2</numero>





<date_debut>2005-06-22T17:02:52.3750000+02:00</date_debut>





<date_fin>2005-06-22T17:02:52.3750000+02:00</date_fin>





<duree>60</duree>





<statut>nouveau</statut>





<materiel>Epandeur 1</materiel>



</Fichier>




Mais, lorsque je crée une deuxième instance, voilà ce que j'obtient dans le contenu du fichier XML :

La page XML ne peut pas être affichée

Impossible d'afficher l'entrée XML en
utilisant la feuille de style XSL. Corrigez l'erreur, puis cliquez sur le bouton
[javascript:location.reload() Actualiser] ou réessayez
ultérieurement.


<hr>

Un seul élément de niveau supérieur est
autorisé dans un document XML. Erreur de traitement de la ressource
file:///D:/SATt...


<Fichier xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-^


Si vous en avoir une réponse, moi y'en a écouter vous avec plaisir.



Au passage, je pense que TheSaib a de l'info la dessus, j'ai vu un post à lui qui disait que arraylist n'est pas serialisable. Si tu peux me renseigner un peu plus
Afficher la suite 

6/26 réponses

Messages postés
728
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
19 janvier 2017
0
Merci
Bidou>le pb c qu'avec ta methode, on serialize la hashtable en dehors du fichier XML qu'on est en train d'écrire :(

----------------------------
C++ forever
C# amateur
Commenter la réponse de scoubidou944
Messages postés
5487
Date d'inscription
dimanche 4 août 2002
Statut
Modérateur
Dernière intervention
20 juin 2013
42
0
Merci
Si tu veux sérializer une collection typée, alors il ne peut pas y avoir de hashtable dedans, d'un point de vue logique (évidemment que c'est faisable). Du coup, on ne se pause même pas la question si c'est faisable ou non de sérializer une collection qui contient en plus une hashtable... (mais à priori je ne vois pas pourquoi ça ne serait pas faisable).


Si maintenant tu veux sérializer une class qui contient un champ qui est une hashtable, pas de problème, la méthode que j'ai postée ci-dessus fonctionne sans soucis. J'ai fait un petit test super rapidement juste pour vérifier mes dires:


[Serializable()]
public class Test
{
private Hashtable t = new Hashtable();
private int i = 0;


public Test()
{
t.Add("a", "b");
}


public int I
{
get { return i; }
set { i = value; }
}


public Hashtable T
{
get { return t; }
set { t = value; }
}
}



public static void SaveFichier(string fileName, Test t)
{
SoapFormatter formatter = new SoapFormatter();


try
{
formatter.Serialize(new FileStream(fileName, FileMode.Create), t);
}
catch
{
throw;
}
finally
{
formatter = null;
}
}


Utilisation :


Test t = new Test();
SaveFichier(@"C:\test.xml", t);

[Pub] http://www.csharpfr.com/auteurdetail.aspx?ID=13319 [\Pub]
C# forever
Commenter la réponse de cs_Bidou
Messages postés
5487
Date d'inscription
dimanche 4 août 2002
Statut
Modérateur
Dernière intervention
20 juin 2013
42
0
Merci
Bon en fait je me suis peut-être un peu emballé sur le poste ci-dessus.
Si tu as une Hashtable dans ta collection (ce qui n'est peut-être pas aussi illogique que je le prétendais) alors tu peux faire comme ceci (j'ai modifié le code ci-dessus):


Rajouter :


[Serializable()]
public class TestCollection : System.Collections.CollectionBase
{
private Hashtable t = new Hashtable();
private int i = 0;


public TestCollection()
{
t.Add("Oui", "Non");
}


public void Add(Test t)
{
this.InnerList.Add(t);
}


public Test this[int i]
{
get { return (Test)this.InnerList[i]; }
}


public int I
{
get { return i; }
set { i = value; }
}


public Hashtable T
{
get { return t; }
set { t = value; }
}
}



Modifier :


public static void SaveFichier(string fileName, TestCollection tc)
{
SoapFormatter formatter = new SoapFormatter();


try
{
formatter.Serialize(new FileStream(fileName, FileMode.Create), tc);
}
catch
{
throw;
}
finally
{
formatter = null;
}
}


Utilisation :


Test t = new Test();
TestCollection tt = new TestCollection();
tt.Add(t);
SaveFichier(@"C:\test.xml", tt);

[Pub] http://www.csharpfr.com/auteurdetail.aspx?ID=13319 [\Pub]
C# forever
Commenter la réponse de cs_Bidou
Messages postés
728
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
19 janvier 2017
0
Merci
j'ai trouvé un lien intéressant :

http://aspzone.com/articles/167.aspx



à partir de la, je recrée une class de config qui permet d'indexer directement par la forme :



oColor = (Color)this["INIT"]["COLOR"]["BACKGROUND"].Value;



Le hic est dans (this.Value est de type object):

void System.Xml.Serialization.IXmlSerializable.WriteXml(System.Xml.XmlWriter w)



if (this.Value != null)

{


// Ca marche mais que pour les type simple sinon j'ai le nom de la
class genre Color [Blue]


w.WriteAttributeString ("value", this.Value.ToString
());




// La ca marche plus, object peut etre une ArrayList, une Color...

/*w.WriteStartElement("value", NS);


XmlSerializer Serializer = new
XmlSerializer(typeof(object));

Serializer.Serialize(w, this.Value);

w.WriteEndElement();

*/

}



[...]

Serialize dictionary

----------------------------
C++ forever
C# amateur
Commenter la réponse de scoubidou944
Messages postés
728
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
19 janvier 2017
0
Merci
http://www.c2i.fr/code.aspx?IDCode=413



je viens de faire un test :



using System.Runtime.Serialization; // SOAP

using System.Runtime.Serialization.Formatters.Soap;



[Serializable()]

public class MonObjetASerialiserType : System.Collections.DictionaryBase, IXmlSerializable

{}



SoapFormatter oSOAPSerial = new SoapFormatter();

System.IO.FileStream oFS = new System.IO.FileStream(@"d:/output2.xml", FileMode.Create);

oSOAPSerial.Serialize(oFS, MonObjetASerialiser);

oFS.Close();

----------------------------
C++ forever
C# amateur
Commenter la réponse de scoubidou944
Messages postés
728
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
19 janvier 2017
0
Merci
voici un autre lien intéressant :

http://www.ftponline.com/vsm/2004_02/online/wahlin/

pour info on peut sérialiser une ArrayList de String sans ajouter le moindre code. Genre une arraylist de mails.
par contre si on passe par un objet intermédiaire qui contient 2 string (1 mail, 1 nom d'expéditeur) la on se tape une erreur de reflexion. (qui a dit que je réfléchis pas assez ? ;p)
donc visiblement mon objet intermédiaire doit implementer un peu de code.

----------------------------
C++ forever
C# amateur
Commenter la réponse de scoubidou944