Søg på DotNyt:
Denne blog er flyttet til www.nielsbrinch.com


torsdag den 25. september 2008

Fil-baseret lagring på Windows Mobile

skrevet af Niels Brinch

Eftersom jeg er måneden blogger i september må jeg hellere få skrevet mindst ét indlæg i september :)

Jeg skrev for en måneds tid siden om at programmere til min mobiltelefon. Jeg skitserede en database-baseret løsning, men noterede i en bisætning, at jeg endte med ikke at anvende det. Grunden er, at det umiddelbart krævede .NET 3.5. Det er svært at vurdere, men jeg vil gætte på man i skal lave telefon-applikationer til .NET 2.0 i hvert fald et år endnu - lidt afhængigt af målgruppen, selvfølgelig. Derfor er det kun fair jeg præsenterer den noget mindre glamourøse filbaserede måde at gemme filer på telefonen.

Der var to måder jeg kunne vælge at lave fil-baseret håndtering af gemte indstillinger:

  1. Tekstfiler
  2. XML-filer

XML er nemt, men i dette tilfælde er tekstfiler nemmere. Jeg valgte den nemmeste løsning, hvilket jeg generelt går ind for at gøre. Det 'rigtigste' ville måske være at gemme en xml-fil ala app.config og anvende den - også så man kan gemme lidt kontekst med indstillingerne - men jeg valgte altså det noget nemmere, nemlig at anvende en tekst-fil for hver indstilling, hvor indstillingens nøgle ganske enkelt er filens filnavn. Enkelt, hurtigt og det virker bare.

Min generelle klasse til at håndtere indstillinger, indeholder tre metoder:

GetFilePath, som henter applikationens installationssti dynamisk ved at anvende lokationen af programmets exe-fil.

public static string GetFilePath(string fileName)
{
string filePath = Assembly.GetExecutingAssembly().GetName().CodeBase;
filePath = filePath.Replace("Timer.exe", fileName);

return filePath;
}

Den metode skal jeg bruge hver gang jeg gemmer eller henter en applikation. Herefter skal jeg bruge to metoder til henholdsvis at gemme indstillinger og hente indstillinger. Jeg har lavet dem så de hver gang tjekker om filen eksisterer og håndterer det pænt. På den måde behøver der ikke være nogen procedure til initialisering af indstillingerne eller lignende - man kan bare begynde at anvende dem.


SetSetting, sørger for at oprette filen hvis den ikke allerede findes og gemmer ganske enkelt den streng som den modtager. Ja, det er en streng, ikke et object. Jeg kunne have valgt at modtage et object som så skulle serialiseres, men jeg havde ikke brug for det og man kommer altså langt med en streng. Som sagt, jeg vælger tit den nemmeste løsning.


private static void SetSetting(string key, string value)
{
string filePath = GetFilePath(key + ".txt");

StreamWriter writer = File.CreateText(filePath);
writer.Write(value);
writer.Close();
}

Det er heldigvis så smart at man bare har skriverettigheder til applikationens eget bibliotek. Jeg er webudvikler og er vant til at webapplikationen skal have rettighed til at skrive i mappen hvis man skal anvende filsystemet. Det er som sagt ikke tilfældet på en telefon. Heldigvis.


GetSetting, sørger for at hente tekststrengen ud fra filen, men returnerer null hvis filen ikke eksisterer. På den måde kan programmøren kende forskel på om indstillingen er "tom" eller "ikke-eksisterende", hvilket er rart at vide, hvis man f.eks. vil have brugeren til at tage stilling til indstillingen.


private static string GetSetting(string key)
{
string filePath = GetFilePath(key + ".txt");

if (!File.Exists(filePath))
{
return null;
}
else
{
StreamReader reader = File.OpenText(filePath);
string value = reader.ReadToEnd();
reader.Close();

return value;
}
}

Næste skridt ville som sagt være serialisering og deserialisering af objekter og selvfølgelig at gemme i en XML-fil i stedet - men slap af. Der er allerede databaseunderstøttelse i .NET 3.5 og det bliver udbredt i løbet af 1 til 2 år. Indtil da fungerer mit filbaserede lagringssystem fint.


Her er hele klassen for en god ordens skyld, så andre let kan anvende den.


using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Data;
using System.IO;

namespace Timer
{
public static class Settings
{
public static string GetFilePath(string fileName)
{
string filePath = Assembly.GetExecutingAssembly().GetName().CodeBase;
filePath = filePath.Replace("Timer.exe", fileName);

return filePath;
}

private static string GetSetting(string key)
{
string filePath = GetFilePath(key + ".txt");

if (!File.Exists(filePath))
{
return null;
}
else
{
StreamReader reader = File.OpenText(filePath);
string value = reader.ReadToEnd();
reader.Close();

return value;
}
}

private static void SetSetting(string key, string value)
{
string filePath = GetFilePath(key + ".txt");

StreamWriter writer = File.CreateText(filePath);
writer.Write(value);
writer.Close();
}
}
}

0 kommentarer

0 Kommentarer:

Send en kommentar

<< Tilbage


 
Til forsiden

Niels Brinch