Laden...

ArrayList serialisieren

Erstellt von KRambo vor 19 Jahren Letzter Beitrag vor 19 Jahren 9.372 Views
K
KRambo Themenstarter:in
355 Beiträge seit 2004
vor 19 Jahren
ArrayList serialisieren

Hi

hab ein kleines Problem. Ich hab ne Klasse, die ich serialisieren möchte. Und zwar hab ich da bools, ints und strings drin, die ich alle zusammen serialisiere und als Dateistream speichere. Jetzt möchte ich auch ArrayLists mitserialisieren.

Klappt soweit auch schon fast, nur krieg ich beim Einlesen immer nur eine leere ArrayList zurück, egal was ich reinspeichere. Kann man ArrayLists gar nicht serialisieren?

Meine Klasse sieht in etwa so aus:


[Serializable()]
public class Settings
{
  ...
  public ArrayList pathAccess = new ArrayList();
  ...
}

Das war mein 1ter Versuch. Klappte nicht, also hab ich die ArrayList als NonSerializable markiert, danach gehts zwar auch fast, jedoch speichert er mir logischerweise die Liste nicht mit ab.

  1. Versuch:

public class Settings
{
  [XmlArrayAttribute("pathAccess")] 
  public ArrayList pathAccess;
}

Geht auch nicht wirklich, gibt zwar bei allen Versuchen keinerlei Fehlermeldungen, aber wird nix abgespeichert 🙁

K
KRambo Themenstarter:in
355 Beiträge seit 2004
vor 19 Jahren
  1. Versuch:
    Hab probiert, das Element mit

[XmlArrayItem(typeof(string))]

zu markieren, funzt genausowenig 🙁

49.485 Beiträge seit 2005
vor 19 Jahren

Hallo KRambo,

ich habe vor ein paar Tagen eine ArrayList problemlos serialisiert. Allerdings gab es zwei Unterschiede: Ich habe den BinarayFormatter benutzt und die ArrayList war nicht in einer Klasse enthalten, sondern ich habe sie direkt also zu serialisierendes Objekt übergeben. Es sollte aber eigentlich auch so gehen, wie du das machst.

HTH

herbivore

4.221 Beiträge seit 2005
vor 19 Jahren

Jage das Ding mal durch diese TestMethode:



		private object TestSerializer(object obj)
		{

			//Opens a file and serializes the object into it in binary format.
			Stream stream = File.Open("data.xml", FileMode.Create);

			BinaryFormatter formatter = new BinaryFormatter();

			formatter.Serialize(stream, obj);
			stream.Close();
   
			//Empties obj.
			obj = null;
   
			//Opens file "data.xml" and deserializes the object from it.
			stream = File.Open("data.xml", FileMode.Open);

			formatter = new BinaryFormatter();

			obj = formatter.Deserialize(stream);
			stream.Close();

			return obj;
		}

		private void button1_Click(object sender, System.EventArgs e)
		{
			//Ein Test-Objekt
			Class1 cls=new Class1();
			cls.ArrayList.Add("Hans");

			//durch den Tester jagen
			Class1 obj=this.TestSerializer(cls) as Class1;

			//ist der Hans noch da ?
			MessageBox.Show(obj.ArrayList[0].ToString());
		}



Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

210 Beiträge seit 2005
vor 19 Jahren

Also wenn du etwas serialisieren willst, was nicht serialisiert werden kann, dann bekommst du schon eine Fehlermeldung vom Compiler. Also die ArrayList ist serialisierbar.
Ich vermute, dass da irgendwas anderes im Code schief läuft. Poste doch mal einen größeren Ausschnitt, vielleicht lieft der Fehler wirklich ganz wo anders.

Blog

Portable WebDAV Library

Windows Server Advanced Power Management
Erweitertes Energie-Management unter Windows

K
KRambo Themenstarter:in
355 Beiträge seit 2004
vor 19 Jahren

Hi Leute

Original von herbivore
Ich habe den BinarayFormatter benutzt und die ArrayList war nicht in einer Klasse enthalten...

Ich hatte zuerst auch den Binary Formatter, nur hab ich mir dann gedacht, als die ArrayList nie gespeichert wurde, ich nehm den XMLSerializer, damit ich sehe, was in der Datei vorgeht. Hat mir bisher noch nicht viel gebracht, die Arraylist wird immer leer in die Datei geschrieben.

Original von exec
Ich vermute, dass da irgendwas anderes im Code schief läuft. Poste doch mal einen größeren Ausschnitt, vielleicht lieft der Fehler wirklich ganz wo anders.

Ok ich werde heute Nachmittag wenn ich zuhause bin die ganze Klasse hier posten inkl der Schreib- und Lesemethoden. Bis auf die ArrayLists gehen auch alle Sachen zu serialisieren...irgendwas ist da noch falsch.

Hab gestern in Google gesucht und da haben manche geschrieben, man(n) muss es markieren, damit der Serializer bzw. der Formatter checkt, dass es ne ArrayList iss. Also mit [XmlArrayItem(typeof(string))] oder so

K
KRambo Themenstarter:in
355 Beiträge seit 2004
vor 19 Jahren

So dies ist meine Klasse, die serialisiert wird:


[Serializable()]
public class Settings
{
	#region Variablen

	// Programm
	public bool modeLocal;

	// Sicherung
	public bool createFolder;
	public bool backupCheckout;

	public int countBackup;
	public int countInterval;

	public string fileFormat;

	// Integration
	public bool startWindows;
	public bool startupMinimized;

	// Pfade
	public string pathLocal;
	public string pathBackup;

                // ArrayList die nicht geht!!
	[XmlArrayItem(typeof(string))]
	public ArrayList pathAccess = new ArrayList();

	#endregion

	#region Konstruktor

	public Settings(){}

	#endregion
}

Und dies sind meine Lese- und Schreibmethoden:


public static Settings LoadSettings()
{
	XmlSerializer serializer = new XmlSerializer(typeof(Settings));
//	BinaryFormatter formatter = new BinaryFormatter();
//	formatter.AssemblyFormat = FormatterAssemblyStyle.Simple;
		
	Settings setting = new Settings();

	using(FileStream file = new FileStream(PROFILE_FILE_NAME,FileMode.Open))
	{
//		setting = (Settings)formatter.Deserialize(file);
		setting = (Settings)serializer.Deserialize(file);

		return setting;
	}
}

public static void SaveSettings(Settings setting)
{
	XmlSerializer serializer = new XmlSerializer(typeof(Settings));
//	BinaryFormatter formatter = new BinaryFormatter();
//	formatter.AssemblyFormat = FormatterAssemblyStyle.Simple;

	using(FileStream file = new FileStream(PROFILE_FILE_NAME,FileMode.Create))
	{
//		formatter.Serialize(file,setting);
		serializer.Serialize(file,setting);
	}
}

Ich glaube da ist nix falsch, oder? Nur warum geht die ArrayList nicht da rein?
Meine XML sieht momentan so aus:

<?xml version="1.0"?>
<Settings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modeLocal>false</modeLocal>
<createFolder>true</createFolder>
<backupCheckout>true</backupCheckout>
<countBackup>10</countBackup>
<countInterval>30</countInterval>
<fileFormat>ddMMyy</fileFormat>
<startWindows>true</startWindows>
<startupMinimized>false</startupMinimized>
<pathLocal>E:&lt;/pathLocal>
<pathBackup>E:&lt;/pathBackup>
<pathAccess />
</Settings>

Wie man sieht ist pathAccess leer. Jetzt ist nur die Frage, warum das ?(
Ich bin ehrlich gesagt fertig mit meinem Latein X(

1.373 Beiträge seit 2004
vor 19 Jahren

Ich schätze, dass die ArrayList ganz einfach keine Element enthält.

MfG VizOne

K
KRambo Themenstarter:in
355 Beiträge seit 2004
vor 19 Jahren

Original von VizOne
Ich schätze, dass die ArrayList ganz einfach keine Element enthält.

MfG VizOne

Denke ich nicht. Hab ich zwar nicht gepostet, aber selbstverständlich füge ich der ArrayList ein neues Element hinzu (vom typ string). Ich glaube nicht, dass es daran liegt, ich glaube eher, dass ich eine Eigenschaft oder was ähnliches in der zu serialisierenden Klasse falsch habe.

Laut google muss man "nur" [XmlArrayItem(typeof(string))] hinzuschreiben. Geht aber genausowenig 🤔

Was ich grad rausgefunden habe: Wenn ich die Datei lösche, in die gespeichert wird, und ich adde ein neues Element zur ArrayList, dann schreibt er die Datei gar nicht neu. Erst wenn die ArrayList wieder leer ist (d.h. nach einem Neustart des Programms).
Langsam wirds konfus ?(

_
416 Beiträge seit 2005
vor 19 Jahren

Hallo,

hab grad mal exakt deinen Code in meine Testapplikation reinkopiert und was soll ich sagen:

<pathAccess>
<string>testcode</string>
</pathAccess>

daher schließ ich mich mal VizOne an. Scheinbar ist in deinem Programm irgendwo noch ein logischer Fehler drin. Setz mal in der SaveSettings-methode einen Haltepunkt und schau ob in der ArrayList was drin ist.

K
KRambo Themenstarter:in
355 Beiträge seit 2004
vor 19 Jahren

Das gibts doch nicht, so ein blöder Fehler. Ich könnt mich ohrfeigen.
Jetzt gehts auch bei mir, hatte wirklich einen Denkfehler. Nachdem ich debuggt hatte, war in der ArrayList das Item drin. Es wurde auch abgespeichert.

Mein Fehler war, dass ich die Konstante PROFILE_FILE_NAME auf den Wert "settings.xml" gesetzt hatte. Nun hab ich daraus Application.StartupPath + @"\settings.xml" gemacht und siehe da: es FUNKTIONIERT 😁

Und ich hab dauernd gedacht, es würde an der Klasse liegen. Tja so kann man falschliegen. Danke an alle die mir geholfen haben =)

K
KRambo Themenstarter:in
355 Beiträge seit 2004
vor 19 Jahren

Hi Leute

Eine Frage hab ich noch, damits perfekt iss:
Wenn ich in die ArrayList Items vom Typ "ListViewItem" reinspeichern möchte, dann bekomme ich folgende Exception:

System.InvalidOperationException: Fehler beim Reflektieren des Typs 'Settings'. ---> System.InvalidOperationException: Fehler beim Reflektieren von Feld 'pathAccess'. ---> System.InvalidOperationException: Fehler beim Reflektieren des Typs 'System.Windows.Forms.ListViewItem'. ---> System.InvalidOperationException: 'System.Drawing.Font' kann nicht serialisiert werden, da kein öffentlicher Standardkonstruktor verfügbar ist.

Weiß da zufällig einer ne Lösung für das Problem ?(

_
416 Beiträge seit 2005
vor 19 Jahren

Hallo,

du solltest auf keinen Fall GUI und Datenhaltung vermischen. und ListViewItem ´gehört in den Bereich GUI. Also am besten du packst in die Arraylist nur die Daten die du auch wirklich speichern willst, und füllst dein ListView wenn du ihn anzeigen willst.

K
KRambo Themenstarter:in
355 Beiträge seit 2004
vor 19 Jahren

Hm das Problem dabei ist, dass ich eigentlich immer 2 Werte speichern sollte oder muss, die auch zusammengehören. Und sowas geht ja nicht direkt zu realisieren, da eine ArrayList ja nur eindimensional ist 🤔

_
416 Beiträge seit 2005
vor 19 Jahren

Hallo,

dann erstell dir doch noch ne Struktur in der du beide Werte speicherst und markier sie auch als XmlSerializable

K
KRambo Themenstarter:in
355 Beiträge seit 2004
vor 19 Jahren

Danke is aber jetzt unnötig, hab ein wenig nachgedacht und kanns nun auch mit ner ArrayList wie ursprünglich gedacht lösen. Trotzdem danke 🙂