在isolatedstoragessettings中存储对象
本文关键字:对象 存储 isolatedstoragessettings | 更新日期: 2023-09-27 18:08:28
我有一个对象,我想存储在isolatedstoragessettings中,我不想在应用程序重新启动时重用它。
我的问题在于,由于某种原因,我编写的代码在重新启动时试图访问键时不记得对象。
namespace MyNameSpace
{
public class WindowsPhoneSettings
{
private const string SelectedSiteKey = "SelectedSite";
private IsolatedStorageSettings isolatedStore = IsolatedStorageSettings.ApplicationSettings;
private T RetrieveSetting<T>(string settingKey)
{
object settingValue;
if (isolatedStore.TryGetValue(settingKey, out settingValue))
{
return (T)settingValue;
}
return default(T);
}
public bool AddOrUpdateValue(string Key, Object value)
{
bool valueChanged = false;
if (isolatedStore.Contains(Key))
{
if (isolatedStore[Key] != value)
{
isolatedStore[Key] = value;
valueChanged = true;
}
}
else
{
isolatedStore.Add(Key, value);
valueChanged = true;
}
return valueChanged;
}
public MobileSiteDataModel SelectedSite
{
get
{
return RetrieveSetting<MobileSiteDataModel>(SelectedSiteKey);
}
set
{
AddOrUpdateValue(SelectedSiteKey, value);
isolatedStore.Save();
}
}
}
}
然后在app . example .cs中实例化windowsphonessettings,并为它创建一个公共的getter和setter。以便能够在整个应用程序中访问它。调试表明,正确的对象被存储在隔离存储中,但当关闭应用程序并重新打开它时,隔离存储似乎是空的。我在模拟器和真实设备上都试过了。正如你所看到的,我在设置对象时调用了save方法。
我在这里做错了什么?
我最终将设置保存到隔离存储中的文件中,因为isolatedstoragessettings似乎从来没有工作过。
所以我的代码最终是这样的: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);
}
}
}
和一个设置类包含我想要保存的东西。可以是:
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: SerializationHelper
如何实现的示例
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);
}
}
存储在isolatedstoragessettings中的对象是使用DataContractSerializer序列化的,因此必须是可序列化的。确保在添加到ISS之前(以及从ISS中删除之后)可以自己序列化(和反序列化)它们。
如果在尝试检索时条目不存在,则可能是它们一开始就无法添加(由于序列化问题)。
下面是我用来将对象保存到隔离存储并从隔离存储加载对象的代码-
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;
}
下面是我用来调用上面的代码-
private void SaveToIsolatedStorage()
{
saveToIsolatedStorage("GameData", GameData);
}
private void LoadFromIsolatedStorage()
{
Object temp;
if (loadObject("GameData", out temp))
{
GameData = (CGameData)temp;
}
else
{
GameData.Reset();
}
}
请注意,我这样保存和恢复的对象很小,并且是可序列化的。如果我的对象包含二维数组或其他不可序列化的对象,那么在使用iso存储之前,我将执行自己的序列化和反序列化。
如果您将RetrieveSetting<T>
更改为:
private T RetrieveSetting<T>(string settingKey)
{
T settingValue;
if(isolatedStore.TryGetValue(settingKey, out settingValue))
{
return (T)settingValue;
}
return default(T);
}
注意,被获取的对象被声明为T
类型而不是object
。