Storing objects in IsolatedStorageSettings

早过忘川 提交于 2019-12-04 10:26:00

I ended up saving the settings to a file in the isolated storage as IsolatedStorageSettings never seemed to work.

So my code ended up like this:

public class PhoneSettings
{
    private const string SettingsDir = "settingsDir";
    private const string SettingsFile = "settings.xml";

    public void SetSettings(Settings settings)
    {
        SaveSettingToFile<Settings>(SettingsDir, SettingsFile, settings);
    }

    public Settings GetSettings()
    {
        return RetrieveSettingFromFile<Settings>(SettingsDir, SettingsFile);
    }

    private T RetrieveSettingFromFile<T>(string dir, string file) where T : class
    {
        IsolatedStorageFile isolatedFileStore = IsolatedStorageFile.GetUserStoreForApplication();
        if (isolatedFileStore.DirectoryExists(dir))
        {
            try
            {
                using (var stream = new IsolatedStorageFileStream(System.IO.Path.Combine(dir, file), FileMode.Open, isolatedFileStore))
                {
                    return (T)SerializationHelper.DeserializeData<T>(stream);
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine("Could not retrieve file " + dir + "\\" + file + ". With Exception: " + ex.Message);
            }
        }
        return null;
    }

    private void SaveSettingToFile<T>(string dir, string file, T data)
    {
        IsolatedStorageFile isolatedFileStore = IsolatedStorageFile.GetUserStoreForApplication();
        if (!isolatedFileStore.DirectoryExists(dir))
            isolatedFileStore.CreateDirectory(dir);
        try
        {
            string fn = System.IO.Path.Combine(dir, file);
            if (isolatedFileStore.FileExists(fn)) isolatedFileStore.DeleteFile(fn); //mostly harmless, used because isolatedFileStore is stupid :D

            using (var stream = new IsolatedStorageFileStream(fn, FileMode.CreateNew, FileAccess.ReadWrite, isolatedFileStore))
            {
                SerializationHelper.SerializeData<T>(data, stream);
            }
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine("Could not save file " + dir + "\\" + file + ". With Exception: " + ex.Message);
        }
    }
}

And a settings class just containing the stuff I want to save. This could be:

class Settings
{
    private string name;
    private int id;

    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    public int Id
    {
        get { return id; }
        set { id = value; }
    }
}

EDIT: Sample of how SerializationHelper could be implemented

public static class SerializationHelper
{
    public static void SerializeData<T>(this T obj, Stream streamObject)
    {
        if (obj == null || streamObject == null)
            return;

        var ser = new DataContractJsonSerializer(typeof(T));
        ser.WriteObject(streamObject, obj);
    }

    public static T DeserializeData<T>(Stream streamObject)
    {
        if (streamObject == null)
            return default(T);

        var ser = new DataContractJsonSerializer(typeof(T));
        return (T)ser.ReadObject(streamObject);
    }
}

Objects stored in IsolatedStorageSettings are serialised using the DataContractSerializer and so must be serializable. Ensure they can be or serialize (and deserialize) them yourself before adding to (and after removing from) ISS.

If the items aren't there when trying to retrieve then it may be that they couldn't be added in the first place (due to a serialization issue).

Here is the code I use to save an object to isolated storage and to load an object from isolated storage -

private void saveToIsolatedStorage(string keyname, object value)
{
  IsolatedStorageSettings isolatedStore = IsolatedStorageSettings.ApplicationSettings;
  isolatedStore.Remove(keyname);
  isolatedStore.Add(keyname, value);
  isolatedStore.Save();
}

private bool loadObject(string keyname, out object result)
{
  IsolatedStorageSettings isolatedStore = IsolatedStorageSettings.ApplicationSettings;

  result = null;
  try
  {
    result = isolatedStore[keyname];
  }
  catch
  {
    return false;
  }
  return true;
}

Here is code I use to call the above -

private void SaveToIsolatedStorage()
{
  saveToIsolatedStorage("GameData", GameData);
}

private void LoadFromIsolatedStorage()
{
  Object temp;
  if (loadObject("GameData", out temp))
  {
    GameData = (CGameData)temp;
  }
  else
  {
    GameData.Reset();
  }
}

Note that the objects I save and restore like this are small and serializable. If my object contains a 2 dimensional array or some other object which is not serializable then I perform my own serialization and deserialization before using iso storage.

What if you changed RetrieveSetting<T> to this:

private T RetrieveSetting<T>(string settingKey)
{
  T settingValue;
  if(isolatedStore.TryGetValue(settingKey, out settingValue))
  {
    return (T)settingValue;
  }
  return default(T);
}

Notice that the object being fetched is being declared as type T instead of object.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!