J'ai fourni un code minimal pour imiter le scénario. Voici le code:Sérialisation binaire tableau non initialisé de struct
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Collections.Generic;
namespace Serialization
{
class Program
{
static void Main(string[] args)
{
string[] annotates = { "1", "2"};
Guides[] g1 = new Guides[2];
g1[0].comments = (string[])annotates.Clone();
g1[1].comments = (string[])annotates.Clone();
Guides[] g2 = new Guides[2];
g2[0].comments = (string[])annotates.Clone();
g2[1].comments = (string[])annotates.Clone();//to be commented later
arrayStruct arrStr1 = new arrayStruct();
arrStr1.guides_array = g1;
arrayStruct arrStr2 = new arrayStruct();
arrStr2.guides_array = g2;
using (MoveSaver objSaver = new MoveSaver(@"C:\1.bin"))
{
MoveAndTime mv1 = new MoveAndTime();
MoveAndTime mv2 = new MoveAndTime();
mv1.MoveStruc = "1";
mv1.timeHLd = DateTime.Now;
mv1.arr = arrStr1;
objSaver.SaveToFile(mv1);
mv2.MoveStruc = "2";
mv2.timeHLd = DateTime.Now;
mv2.arr = arrStr2;
objSaver.SaveToFile(mv2);
}
using (MoveSaver svrObj = new MoveSaver())
{
List<MoveAndTime> MVTobjs = svrObj.DeSerializeObject(@"C:\1.bin");
foreach (MoveAndTime item in MVTobjs)
{
Console.WriteLine(item.arr.guides_array[0].comments[0]);
}
}
}
}
public class MoveSaver : IDisposable
{
public void Dispose()
{
if (fs != null)
{
fs.Close();
}
}
FileStream fs;
StreamWriter sw;
public string filename { get; set; }
public MoveSaver(string FileName)
{
this.filename = FileName;
fs = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite);
}
public MoveSaver()
{
}
~MoveSaver()
{
if (fs != null)
{
fs.Close();
}
}
public List<MoveAndTime> DeSerializeObject(string filename)
{
List<MoveAndTime> retList = new List<MoveAndTime>();
MoveAndTime objectToSerialize;
Stream stream = File.Open(filename, FileMode.Open);
BinaryFormatter bFormatter = new BinaryFormatter();
while (stream.Position != stream.Length)
{
objectToSerialize = (MoveAndTime)bFormatter.Deserialize(stream);
retList.Add(objectToSerialize);
}
stream.Close();
return retList;
}
public bool SaveToFile(MoveAndTime moveTime)
{
try
{
BinaryFormatter bformatter = new BinaryFormatter();
bformatter.Serialize(fs, moveTime);
return true;
}
catch (Exception)
{
return false;
}
}
}
[Serializable]
public struct MoveAndTime
{
public string MoveStruc;
public DateTime timeHLd;
public arrayStruct arr;
}
[Serializable]
public struct arrayStruct
{
public Guides[] guides_array;
}
[Serializable]
public struct Guides
{
public string[] comments;
public string name;
}
}
Dans ce code, une structure contient plusieurs structures, dont l'une contient un tableau. Essayez le code et il compile bien, mais dans le scénario réel tout le tableau n'est pas rempli, il y aurait donc d'autres éléments de tableau non spécifiés. Pour voir cet effet (en action!) Commentez la ligne g2[1].comments = (string[])annotates.Clone();
et essayez le code maintenant. Vous ferez face à une erreur lors de la désérialisation. Comment puis-je l'éviter? Devrais-je définir la structure contenant le tableau en tant que classe et tous les nouveaux (j'espère que je suis à la recherche d'une solution de type structuré)?
Modifier: I Modifié les structures en classe et en ajoutant chaque instance, cela fonctionne correctement. Voici le code:
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Collections.Generic;
namespace Serialization
{
class Program
{
static void Main(string[] args)
{
string[] annotates = { "1", "2"};
GuidesClass[] g1 = new GuidesClass[2];
g1[0] = new GuidesClass();
g1[0].comments = (string[])annotates.Clone();
g1[1] = new GuidesClass();
g1[1].comments = (string[])annotates.Clone();
GuidesClass[] g2 = new GuidesClass[2];
g2[0] = new GuidesClass();
g2[0].comments = (string[])annotates.Clone();
g2[1] = new GuidesClass();
//g2[1].comments = (string[])annotates.Clone();
array_cls arrStr1 = new array_cls();
arrStr1.guides_array = g1;
array_cls arrStr2 = new array_cls();
arrStr2.guides_array = g2;
using (MoveSaver objSaver = new MoveSaver(@"C:\1.bin"))
{
M_T mv1 = new M_T();
M_T mv2 = new M_T();
mv1.MoveStruc = "1";
mv1.timeHLd = DateTime.Now;
mv1.arr = arrStr1;
objSaver.SaveToFile(mv1);
mv2.MoveStruc = "2";
mv2.timeHLd = DateTime.Now;
mv2.arr = arrStr2;
objSaver.SaveToFile(mv2);
}
using (MoveSaver svrObj = new MoveSaver())
{
List<M_T> MVTobjs = svrObj.DeSerializeObject(@"C:\1.bin");
foreach (M_T item in MVTobjs)
{
Console.WriteLine(item.arr.guides_array[0].comments[0]);
}
}
}
}
public class MoveSaver : IDisposable
{
public void Dispose()
{
if (fs != null)
{
fs.Close();
}
}
FileStream fs;
StreamWriter sw;
public string filename { get; set; }
public MoveSaver(string FileName)
{
this.filename = FileName;
fs = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite);
}
public MoveSaver()
{
}
~MoveSaver()
{
if (fs != null)
{
fs.Close();
}
}
public List<M_T> DeSerializeObject(string filename)
{
List<M_T> retList = new List<M_T>();
M_T objectToSerialize;
Stream stream = File.Open(filename, FileMode.Open);
BinaryFormatter bFormatter = new BinaryFormatter();
while (stream.Position != stream.Length)
{
objectToSerialize = (M_T)bFormatter.Deserialize(stream);
retList.Add(objectToSerialize);
}
stream.Close();
return retList;
}
public bool SaveToFile(M_T moveTime)
{
try
{
BinaryFormatter bformatter = new BinaryFormatter();
bformatter.Serialize(fs, moveTime);
return true;
}
catch (Exception)
{
return false;
}
}
}
[Serializable]
public class M_T
{
public string MoveStruc;
public DateTime timeHLd;
public array_cls arr;
}
[Serializable]
public class array_cls
{
public GuidesClass[] guides_array = new GuidesClass[10];
}
[Serializable]
public class GuidesClass
{
public string[] comments;
public string name;
}
}
Quelle est l'erreur? – Oded
Par curiosité, ** pourquoi ** sont-ils des structs? Ils ne ressemblent pas à des structures typiques (surtout parce qu'ils sont mutables), et sans une bonne raison, ils devraient être des classes par défaut. –
@Oded: "Le flux d'entrée n'est pas un format binaire valide" et, dans le code actuel, l'erreur concerne l'en-tête binaire. Essayez de compiler le code avec la ligne commentée et vous verrez l'erreur. –