Jan.30

Objecten & objectstructuren opslaan als bestand

In dit artikeltje wil ik je laten zien hoe je gemakkelijk door middel van 2 methoden objectgegevens binair in een file op kunt slaan en weer op kunt halen. Er zijn heel wat artikelen aan serialization gewijdt. Deze gaan veel dieper als dit artikeltje. In dit geval gaat het erom hoe serialiseren en deserialiseren we op een simpele, snelle en correcte manier.

Het opslaan van een object of een objectstructuur als bestand is al mogelijk sinds de eerste versie van het .NET framework. Met een duur woord heet dit serialization (opslaan) en deserialization (ophalen/laden). Het opslaan als bestand is 1 vorm maar je kunt bijvoorbeeld de gegevens ook in een MemoryStream of bijv. de Application State van een ASP.NET applicatie opslaan. Verder is de vorm waarmee de gegevens worden opgeslagen te bepalen. Twee van de mogelijkheden zijn binair of in XML formaat. Dit laatste heeft wat nadelen aangezien niet alle gegevens van een object kunnen worden opgeslagen.

Voorwaarden
Een voorwaarde om een object op te kunnen slaan is dat de betreffende class voorzien is van het attribuut [Serializable]. Dus…

[Serializable] public class AClass
{
...
}

Op het moment dat een instantie (object) van deze class wordt geserializeerd. Dan zullen ook alle gerelateerde velden (properties) worden geserializeerd. Stel…

[Serializable] public class Employee
{
public Address HomeAddress;
...
}

public class Address
{
public string Street;
public string HouseNr;
public string Zip;
}

We hebben dus een werknemer (employee) met daaraan gekoppeld een thuis adres (HomeAddress). Op het moment dat we Employee serializeren zal ook het HomeAddress worden geserializeerd. In dit voorbeeld zal dit echter een exception opleveren aangezien de Address class niet het serializable attribuut bevat.


[Serializable] public class Address
{
...

Bovenstaande code is dus wel OK. Het is overigens ook mogelijk velden expliciet niet mee te laten serializeren. Dit kan worden geregeld door het NonSerialized attribuut te zetten op het specifieke veld.


[Serializable] public class Employee
{
[NonSerialized] public Address HomeAddress;
...
}

In bovenstaande geval hoeft de Address class dus ook het attribuut serializable niet te bevatten.

Verder is het van belang in de gaten te houden dat als een object of objectstructuur is geserializeerd en een class in de objectstructuur wordt daarna aangepast, de geserializeerde gegevens niet meer kunnen worden opgehaald. De binaire gegevens kunnen dan niet meer gemapped worden op het aangepaste type.

Wanneer?
Wanneer is serializatie handig om te gebruiken? Stel je hebt een WinForms applicatie geschreven waarbij je ingevoerde gegevens in een soort projectbestand op wilt slaan. Hiervoor kun je prima binaire serializatie gebruiken.

Ook kan het handig zijn bij webapplicaties. Zo is het bijvoorbeeld mogelijk via SQL Management Objects (SMO), alle mogelijke gegevens van een SQL database (tabellen, velden, primary keys, foreign keys, indexen etc…) op te halen dit proces vergt echter flink wat tijd. Je zou in dat geval een objectstructuur kunnen creeeren bij het ophalen van deze gegevens die overeenkomt met de databaseindeling. Deze structuur vervolgens serializeren naar een bestand en deze vervolgens bij elke request inlezen om gegevens over de database te verkrijgen. Dit kan natuurlijk alleen als de database qua structuur niet wijzigt.

Verder heeft binair opslaan (en dan niet perse als bestand) in sommige gevallen voordelen boven het vasthouden van een referentie naar een object of objectstructuur. Je kunt hiermee objecten of objectstructuren dupliceren.

De code
Ter zake. Hieronder vindt je de code waarmee een object of objectstructuur kan worden opgeslagen op schijf en weer opgehaald. Het mooie is dat bij het ophalen niet noodzakelijk is te weten welk objecttype er terug wordt gegeven.

LET OP: Via de printversie (links boven en onder) kun je de code kopieren.

De code kan dus alsvolgt worden gebruikt:

//Opslaan
Employee emp = new Employee()
emp.Name = "Ton Snoei";
...
SerializeObject(emp,@"c:test.bin");

//ophalen
Employee x = (Employee) DeSerializeObject(@"c:test.bin");

Jan.09

.NET Internationalisatie (Globalization) en een library met internationale gegevens ter download

Zoals elke gemiddelde .NETter weet is binnen het .NET framework een stuk opgenomen wat localisatie van software vergemakkelijkt, de System.Globalization namespace. De voornaamste klassen binnen deze namespace zijn CultureInfo, RegionInfo en sinds .NET 2.0 CultureAndRegionInfoBuilder de meest belangrijke.

CultureInfo
Van de CultureInfo klasse kan een object worden geinstantieerd door een CultureCode mee te geven. Een culture is eigenlijk een combinatie van taal + land. Bijvoorbeeld: Frans – Belgie (fr-BE) , Nederlands – Belgie (nl-BE). De landcode of eigenlijk regioncode wordt volgens ISO 3166-1 met hoofdletters geschreven de taalcode (ISO 639) wordt lowercase geschreven. Dit samen maakt een cultuur. Een cultuur verteld vervolgens iets over de formatting van datum/tijd en numerieke waarden. Een .NET culture wordt ook wel ‘locale’ genoemd in de “unmanaged” volksmond.

RegionInfo
De RegionInfo klasse kan worden gebruikt voor het ophalen van gegevens van een land. Ook bij de constructie van een RegionInfo instantie dient een RegionCode te worden meegegeven. Het gaat hier om de 2-karakters lange ISO3166-1 code. Vervolgens heb je dan toegang tot de NativeName (naam in de taal van het land/region), EnglishName en niet te vergeten de Currency (Valuta).

De hele system.globalization namespace zit goed in elkaar en kan je heel wat programmeerwerk uit handen nemen bij het bouwen van internationale applicaties. Echter, CultureInfo en RegionInfo ondersteunen niet alle landen en cultures, maar alleen de belangrijke. Hoe deze schifting plaats heeft gevonden is mij niet duidelijk. Ik zou zeggen wie daar meer over weten, sta op en reageer! ;-). Het leek mij zelf leuk om informatie te hebben over alle landen, valuta, talen etc.. Ik ben via het web op zoek gegaan naar aan internationalisatie gerelateerde gegevens. Dit heeft geresulteerd en een verzameling data die je hieronder kunt downloaden

Internationalisatie Library
Dit library bevat heel veel gegevens over een land. Het is verzameld via allerlei verschillende webpagina’s en samengevoegd tot 1 geheel. De gegevens zijn dus niet 100% betrouwbaar en ik neem wat dat betreft dan ook geen enkele verantwoordelijkheid op me. (Geleden schade.. etc etc kun je dan ook niet op mij verhalen šŸ˜‰ ) Ik heb trouwens eerlijk gezegd geen idee of op welk van deze gegevens een copyright rust. Mocht er wat dit betreft bezwaren zijn dan hoor ik dat graag. Ik zal in iedergeval waar mogelijk de noodzakelijk stappen ondernemen om te zorgen dat rechthebbende geen verdere schade zullen leiden.

..ok, nu ter zake.

Het library bevat de volgende tabellen:

  • Continent – Continenten
  • Region – Landen
  • Culture – Taal – Land combinaties (Locales)
  • Currency – Valuta
  • Language – Talen
  • TimeZone – Tijdzones
  • TimeZoneNames – Tijdzone namen
  • RegionCurrency – Koppeling land-valuta
  • RegionIP – Koppeling land-internet IP adres
  • RegionTimeZone – Koppeling land-tijdzone
  • RegionLanguage – Koppeling land-taal
  • RegionName – Namen van een land inde verschillende talen
  • PrimaryAdministrativeDivision – Primaire onderverdeling van een land (bijv. Provincie)
  • PrimaryAdministrativeDivisionPopulation – Bevolkingsaantallen van een primaire administratieve divisie per jaar
  • SecondaryAdministrativeDivision – Secundaire onderverdeling van een land (bijv. Gemeente)
  • SecondaryAdministrativeDivisionPopulation – Bevolkingsaantallen van een secundaire administratieve divisie per jaar
  • De regio (=land) tabel bevat belangrijk informatie zoals:

  • Volledige benaming
  • Verkorte benaming
  • Engelse benaming
  • Hoofdstad (Capital)
  • Top Level Domain
  • Dialing Code
  • National Dialing Code
  • Primary Administrative Division Name
  • Secundary Administrative Division Name
  • Zomertijd (Day Light Savings) (ja/nee)
  • Voertuigidentificatiecode
  • Voor elk land zijn er in de RegionName tabel de namen van een land in gemiddeld +/- 50 verschillende talen opgenomen. Mocht je hier vierkantjes als karakters tegenkomen dan heb je waarschijnlijk de chinese karakterset niet geinstalleerd.

    Kortom, een bak informatie heb je interesse dan kun je de zaak hier downloaden in zowel xml, mdb (MS Access 2000) als sdf (SQL 2005 Everywhere Edition) formaat. Mocht je toevoegingen hebben wees dan zo vriendelijk deze ook met ons allen te delen!!

    (Bevolkingsaantallen per land zijn bijvoorbeeld nog niet aanwezig en deze kunnen niet zonder meer worden afgeleid uit de primaire administratieve divisies. Bijvoorbeeld in landen als die van het midden-oosten leven veel nomaden leven die in geen enkele divisie zijn ingedeeld.)

    Download opties

  • GlobalizationXML.zip (XML bestanden)
  • GlobalizationMDB.zip (MS Access database)
  • GlobalizationSDF.zip (SQL Server 2005 Compact Edition / Everywhere Edition database)
  • Vlaggen

  • Flags.zip
  • Meer weten over Globalization in .NET:
    .NET Magazine Maart 2006