úterý 15. ledna 2008

C# a .NET: Uložení objektů do Application Settings

Do jistého projektu (bakalářská práce) jsem potřeboval implementovat samozřejmou věc, jako je Nastavení. Nejdřív jsem chtěl vše řešit pomocí xml souborů. Dříve jsem s XML v .NETu nedělal, takže jsem vše zjišťoval tak nějak za pochodu. A protože mám hodně zanořené elementy (cca 10 elementů zanořených do sebe), byla by tvorba takového xml dost těžkopádná.

Pak jsem objevil Application Settings a zajásál jsem. Ovšem předčasně, jak se mi obvykle stává. Sice v MSDN píší toto: "The Type of the setting is the .NET Framework type that the setting represents. A setting can be of any type.", ale odkazové typy se mi nepodařilo do settings nacpat. Přemýšlel jsem, jak to udělat, protože jsem potřeboval uložit celý List stringů, a ukládat jeden po druhém mi přišlo opravdu hnusné.

Po chvíli pátrání jsem si řekl, že budu jakýkoliv odkazový typ (říkejme pro jednoduchost jakýkoliv objekt) serializovat a ukládat jako string a pak provedu deserializaci. Peklo nastalo ve chvíli, kdy jsem chtěl binární podobu objektu uložit jako string, a poté z tohoto stringu udělat opět binární podobu a deserializovat. Asi po hodině jsem dal dohromady funkční kód.

Důležité jsou tyto metody:
Convert.ToBase64String(byte[])
Convert.FromBase64String(string)
Mají několik přetížených variant, ale to lze dohledat v MSDN.

internal string Serializuj(object objektKSerializaci)
{
Stream lStream = new MemoryStream();
BinaryFormatter lFormatter = new BinaryFormatter();
string vysledek = string.Empty;
if (objektKSerializaci.GetType().IsSerializable)
{
try
{
lFormatter.Serialize(lStream, objektKSerializaci);
using (StreamReader reader = new StreamReader(lStream))
{
lStream.Position = 0;
byte[] b = new byte[lStream.Length];
lStream.Read(b, 0, b.Length);
vysledek = Convert.ToBase64String(b);
}
}
finally
{
lStream.Close();
}
}
return vysledek;
}

internal object Deserializuj(string serializovanyObjekt)
{
BinaryFormatter lFormatter = new BinaryFormatter();
Stream lStream = new MemoryStream();
object vyslednyObjekt;
BinaryWriter lWriter = new BinaryWriter(lStream);
try
{
byte[] b = Convert.FromBase64String(serializovanyObjekt);
lWriter.Write(b);
lStream.Position = 0;
vyslednyObjekt = lFormatter.Deserialize(lStream);
}
finally
{
lStream.Close();
}
return vyslednyObjekt;
}

Omlouvám se, za způsob formátovaní ale zatím jsem nepřišel na to, jak mít pěkně odsazený text, a po třetím pokusu, kdy jsem ručně odsazoval řádek po řádku, jsem to vzdal. Přinejhorším to vložím jako obrázek.

19.1.2008
--------------
Tak jsem našel způsob, jak to alespoň trochu formátovat. Bohužel, obarvovat zdrojový kód musím ručně, slovo po slově. Pokud někdo znáte nějaký pohodlnější způsob, budu moc vděčný.

Žádné komentáře:

Okomentovat