Geeks With Blogs
Light Up the Web Blog about programming in Silverlight
In this article, I would like to describe Isolated Storage Memory in Silverlight 2.0 RTW. Isolated storage is a place on local disk, where applications have all access privileges to store their data. Default settings, give applications 1 MB space but this can be changed by administrator.

This memory space let application read files and create new, without special permissions. I used this feature, for example to store user settings (user name, application skins, etc.), local high scores for Silverlight game or as a flag in survey, to remember if user already voted today. It’s very useful and sooner or later you will use it ;)

Let’s dance

As an example, we will create simple demo, which will remember our name and will show it every time when we turn on application on our computer. 

First, let's add two controls to "enter name":
<TextBox Height="32" x:Name="EnterName" Width="192" Text="Enter your name here" TextWrapping="Wrap"/>
<Button Height="28" x:Name="SubmitButton" Width="106" Foreground="#FF313131" Content="Submit" Click="SubmitButton_Click">

and one control to "show entered name"
<TextBlock Height="91" x:Name="NameTextBlock" Width="284" TextWrapping="Wrap" >
   <Run x:Name="UserName" FontFamily="Comic Sans MS" FontSize="36" FontWeight="Bold" Text="" />
</TextBlock>

 Then, add methods to write and read name from file in Isolated Storage. These methods are invoked from SubmitButton_Click event and from Page.Loaded event. To do this, we need IsolatedStorageFile object 

IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication(); 

which we will use to check if file with user name exist 

if (!isf.FileExists(“our_file.txt”)) 

and to create FileStream object 

IsolatedStorageFileStream isfs = new IsolatedStorageFileStream(“our_file.txt”, FileMode.Open, isf);

Now, all we have to do is use for example StreamReader and make all operation like with simple text file on desktop application. 

StreamReader sr = new StreamReader(isfs);
userName = sr.ReadToEnd();
sr.Close();

To save user's name in Isolated Storage, open file with different FileMode, for example

IsolatedStorageFileStream isfs = new IsolatedStorageFileStream(“our_file.txt”, FileMode.Create, isf);

 and instead of StreamReader, use StreamWriter

StreamWriter sw = new StreamWriter(isfs); 

All other parts of code for save method are similar to read parts.

Completed code for save method:
private void SaveUserName(string name)
{
     IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication();
     IsolatedStorageFileStream isfs = new IsolatedStorageFileStream(FILE_NAME, FileMode.Create, isf);
     StreamWriter sw = new StreamWriter(isfs);
     try
     {
            sw.WriteLine(String.Format("{0}", name));
     }
     catch (Exception ee) { }
     finally
     {
            sw.Close();
            isfs.Close();
            isfs.Dispose();
            isf.Dispose();
            sw.Dispose();
      }

}
 

Completed code for read method:
private string ReadNameIfExist()
{
      string userName = String.Empty;
      IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication();
      if (!isf.FileExists(FILE_NAME))
            return userName;

      IsolatedStorageFileStream isfs = new IsolatedStorageFileStream(FILE_NAME, FileMode.Open, isf);
      try
      {
            StreamReader sr = new StreamReader(isfs);
            userName = sr.ReadToEnd();
            sr.Close();
      }
      catch (Exception e) { }
      finally
      {
            isf.Dispose();
      }
      return userName;

}

Working example play demo - (remember to refresh web page F5)

Source code is below in “source code” section.

Make it easier

If you don't want to play with Streams, etc., you can simply use IsolatedStorageSettings class. This class works as a dictionary, where you have keys and values, so inserting and getting values is fairly easy.

Declaration

private IsolatedStorageSettings isolatedSettings = IsolatedStorageSettings.ApplicationSettings;

Save data

try
{
isolatedSettings
.Add("name", name);
}
catch (ArgumentException ex)
{
// error message
}

Read data

string name = String.Empty;
try
{
name
= (string)isolatedSettings["name"];
}
catch (System.Collections.Generic.KeyNotFoundException)
{
// error
name
= "anonymous";
}

Update data

isolatedSettings["name"] = "new name";

Delete data

isolatedSettings.Remove("name");

Clear all data

isolatedSettings.Clear();

Inserted data's count

isolatedSettings.Count();

Key's count

isolatedSettings.Keys;

Value's count

isolatedSettings.Values;

So as you can see, IsolatedStorageSettings makes our work easy and more pleasant, we have less code and work :)

How to increase amount of available data space (quota)?

We know that by default we have only 1 MB free space per application and usually, if we would like to cache some images or videos, it's not enough. To increase our space we need to ask user and if he agree, we can have even 8,589,934,592Gb space for our application (8,589,934,592Gb = long.MaxValue). :-)

To ask him, we need invoke method "IncreaseQuotaTo()", like in this example (we ask for 100MB):

private void SubmitButton_Click(object sender, RoutedEventArgs e)
{
 
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
     
{
             Int64 sizeNeeded
= 1024 * 1024 * 100;
             
if (sizeNeeded > isf.AvailableFreeSpace)
             
{
                 Int64 newValue
= isf.Quota - isf.AvailableFreeSpace + sizeNeeded;
                 
if (isf.IncreaseQuotaTo(newValue))
                 
{
   
// save data
     
}
 
}
 
}
}


User's question:

We need ask him only once and if he agree, then we can save data whenever we want. Question looks like on picture above. Unfortunately, we can not modify text in question and this have to be invoked from event. It's mean that we can not ask user during  application's initialization
, only when he click something.

Attention IncreaseQuotaTo Localization Bug:
If your users have a Operating System (OS) other than in English version, you may not ask him question about increase quota and "IncreaseQuotaTo()" will automatically result with false. This happened for all user with no English version OS! This bug is well known for Microsoft and you can read more about it here: http://silverlight.net/forums/p/51485/135114.aspx


Where is that place

To find a place where exactly is our file with user's name, we have to use debugger in Visual Studio. Place breakpoint on isf variable and run application in debug mode.

 

 

Variable "m_AppFilePath" contain real path to Isolated Storage directory and file with user's name. This path is not easy to remember and it could looks like this

"C:\\Users\\ToJaUser\\AppData\\LocalLow\\Microsoft\\Silverlight\\is\\3tumcpvn.hf1\\wrelfaen.uut\\1\\s\\rtqyd4tgtuurqnzlqaf3otinrvcefdf4aeqlkxhw0dltde2t2uaaaeaa\\f"

Deleting isolated storage

If we don't want to keep any more data for Silverlight application in Isolated Storage, we can write program to clear this space or just click right button on any Silverlight application and choose "Silverlight Configuration"

 

 Then go to "Application Storage" tab.

 

 

In this window we can see all information about every Silverlight application which saved data on our disk. We have also opportunity to delete these files with only one click.
 

Source code

Working demo

Resources

  • MSDN System.IO.IsolatedStorage Namespace - link
  • “Switch On The Code” blog - linkit’s a little overdue but this was my first article about Isolated Storage Memory which I found few months ago.


kick it on DotNetKicks.com

 
Bests Regards ,
Jacek Ciereszko
also
http://jacekciereszko.pl – blog in polish

Posted on Sunday, June 15, 2008 10:56 PM | Back to top

Copyright © Jacek | Powered by: GeeksWithBlogs.net | Join free