【WP8】自定义配置存储类
之前在WP7升级到WP8的时候遇到配置不兼容的问题
情景:之前只有一个WP7版本,现在需要发布WP8版本,让用户可以从原来的WP7版本升级到WP8版本
一般情况下从WP7升级到WP8没什么问题
但是在项目中升级到WP8的时候,原先在WP7下保存在IsolatedStorageSettings的数据都不出来,经过调试发现
1、IsolatedStorageSettings存放数据的隔离存储控件的"__ApplicationSettings"文件中,存放的格式如下 {"test":"TestData"}
<ArrayOfKeyValueOfstringanyType xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<KeyValueOfstringanyType>
<Key>test</Key>
<Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema" i:type="d3p1:string">TestData</Value>
</KeyValueOfstringanyType>
</ArrayOfKeyValueOfstringanyType>
2、但是原来的项目中使用了友盟WP7版本,后来的项目中使用的是WP8版本,友盟会向"__ApplicationSettings"文件中写入数据,如下:
UmengSDK.Business.OnlineConfigManager+OnlineConfig, UmengAnalyticsWP7, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null
<ArrayOfKeyValueOfstringanyType xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<KeyValueOfstringanyType>
<Key>test</Key>
<Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema" i:type="d3p1:string">TestData</Value>
</KeyValueOfstringanyType>
<KeyValueOfstringanyType>
<Key>device_id</Key>
<Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema" i:type="d3p1:string">0BBB2DF41DD5688A25517F2968339DC0</Value>
</KeyValueOfstringanyType>
<KeyValueOfstringanyType>
<Key>wp_device</Key>
<Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema" i:type="d3p1:string">1C43AC07795C55C2ADA78B0DD5A79B3660A7D137</Value>
</KeyValueOfstringanyType>
<KeyValueOfstringanyType>
<Key>config</Key>
<Value xmlns:d3p1="http://schemas.datacontract.org/2004/07/UmengSDK.Business" i:type="d3p1:OnlineConfigManager.OnlineConfig">
<d3p1:Interval>30</d3p1:Interval>
<d3p1:LastConfigTime>Wed Jul 02 00:43:35 CST 2014</d3p1:LastConfigTime>
<d3p1:Policy>BATCH_AT_LAUNCH</d3p1:Policy>
</Value>
</KeyValueOfstringanyType>
</ArrayOfKeyValueOfstringanyType>
3、而上面数据到了WP8上就不能正常读取原来存放的数据(如果在WP8项目中用WP7版的友盟则可以正常读取),导致原来存放的其他信息也读取不出来
4、下面试图自定义一个与 IsolatedStorageSettings 功能类似的类用于小数据的存取,避免第三方类库对"__ApplicationSettings"文件的修改导致一些兼容性问题
IsolatedStorageSettings 存放的是键值对,也就是字典模型,我们需要把Dictionary序列化到文件中,但是Dictionary不支持直接序列化,先对Dictionary进行扩展,让其支持序列化
using System;
using System.Collections.Generic;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization; namespace XTuOne.Common.Helpers
{
/// <summary>
/// 可序列化的Dictionary
/// </summary>
[XmlRoot("Dictionary")]
public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable
{
#region 构造函数,调用基类的构造函数 public SerializableDictionary()
{
} public SerializableDictionary(IDictionary<TKey, TValue> dictionary)
: base(dictionary)
{
} public SerializableDictionary(IEqualityComparer<TKey> comparer)
: base(comparer)
{
} public SerializableDictionary(int capacity)
: base(capacity)
{
} public SerializableDictionary(int capacity, IEqualityComparer<TKey> comparer)
: base(capacity, comparer)
{
} public SerializableDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer)
: base(dictionary, comparer)
{
} #endregion #region IXmlSerializable 接口的实现 public XmlSchema GetSchema()
{
throw new NotImplementedException();
} /// <summary>
/// 从对象的XML表示形式生成该对象
/// </summary>
/// <param name="reader"></param>
public void ReadXml(XmlReader reader)
{
var keySerializer = new XmlSerializer(typeof (TKey));
var valueSerializer = new XmlSerializer(typeof (TValue));
bool wasEmpty = reader.IsEmptyElement;
reader.Read(); if (wasEmpty)
return;
while (reader.NodeType != XmlNodeType.EndElement)
{
reader.ReadStartElement("Key");
TKey key = (TKey) keySerializer.Deserialize(reader);
reader.ReadEndElement(); reader.ReadStartElement("Value");
TValue value = (TValue) valueSerializer.Deserialize(reader);
reader.ReadEndElement();
this.Add(key, value);
reader.MoveToContent();
}
reader.ReadEndElement();
} /// <summary>
/// 将对象转换为其XML表示形式
/// </summary>
/// <param name="writer"></param>
public void WriteXml(XmlWriter writer)
{
var keySerializer = new XmlSerializer(typeof (TKey));
var valueSerializer = new XmlSerializer(typeof (TValue));
foreach (TKey key in this.Keys)
{
writer.WriteStartElement("Key");
keySerializer.Serialize(writer, key);
writer.WriteEndElement(); writer.WriteStartElement("Value");
TValue value = this[key];
valueSerializer.Serialize(writer, value);
writer.WriteEndElement();
}
} #endregion
}
}
5、使用系统的Xml序列化功能保存数据
using System;
using System.IO;
using System.IO.IsolatedStorage;
using System.Windows;
using System.Xml.Linq;
using System.Xml.Serialization; namespace XTuOne.Common.Helpers
{
public class XmlHelper
{
private XmlHelper()
{
} /// <summary>
/// 序列化对象到文件
/// </summary>
/// <param name="file">文件路径:"/test.xml"</param>
/// <param name="obj"></param>
public static void Serialize<T>(string file, T obj)
{
using (var sf = IsolatedStorageFile.GetUserStoreForApplication())
{
using (var fs = new IsolatedStorageFileStream(file, FileMode.OpenOrCreate, FileAccess.Write, sf))
{
var serializer = new XmlSerializer(obj.GetType());
serializer.Serialize(fs, obj);
}
}
} /// <summary>
/// 反序列化文件到对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="file">文件路径:"/test.xml"</param>
public static T Deserialize<T>(string file)
{
using (var sf = IsolatedStorageFile.GetUserStoreForApplication())
{
var serializer = new XmlSerializer(typeof(T));
using (var fs = sf.OpenFile(file, FileMode.Open, FileAccess.Read))
{
return (T)serializer.Deserialize(fs);
}
}
} /// <summary>
/// 读取配置文件的信息
/// </summary>
/// <param name="file">前面不加/</param>
/// <param name="node">用.隔开(例如App.Version)</param>
/// <param name="attribute"></param>
public static string GetConfigValue(string file,string node, string attribute)
{
var configFile = Application.GetResourceStream(new Uri(file, UriKind.Relative));
return GetXmlValue(configFile.Stream, node, attribute);
} private static string GetXmlValue(Stream stream, string node, string attribute)
{
var configDoc = XDocument.Load(stream);
XElement temp = null;
foreach (var n in node.Split('.'))
{
if (temp == null)
{
temp = configDoc.Element(n);
continue;
}
temp = temp.Element(n);
} if (temp == null)
{
throw new NullReferenceException();
}
return temp.Attribute(attribute).Value;
} }
}
XmlHelper
// *************************************************
//
// 作者:bomo
// 小组:WP开发组
// 创建日期:2014/6/21 14:55:56
// 版本号:V1.00
// 说明:
//
// *************************************************
//
// 修改历史:
// Date WhoChanges Made
// 2014/6/21 14:55:56 bomo Initial creation
//
// ************************************************* using System.IO;
using System.IO.IsolatedStorage;
using XTuOne.Common.Helpers; namespace XTuOne.Utility.Helpers
{
/// <summary>
/// 自定义应用程序配置(相当于IsolatedStorageSetting)
/// </summary>
public class ApplicationSetting
{
/// <summary>
/// 保存配置的文件名
/// </summary>
private readonly string filePath; private readonly SerializableDictionary<string, object> dictionary; public ApplicationSetting(string filePath)
{
this.filePath = filePath;
//读取配置
using (var sf = IsolatedStorageFile.GetUserStoreForApplication())
{
var directory = Path.GetDirectoryName(filePath);
if (directory != null)
{
if (sf.DirectoryExists(directory))
{
sf.CreateDirectory(directory);
}
} dictionary = sf.FileExists(filePath)
? XmlHelper.Deserialize<SerializableDictionary<string, object>>(filePath)
: new SerializableDictionary<string, object>();
}
} /// <summary>
/// 通过索引赋值需要显式保存
/// </summary>
public object this[string key]
{
get { return Contains(key) ? dictionary[key] : null; }
set { dictionary[key] = value.ToString(); }
} public T Get<T>(string key)
{
return (T) dictionary[key];
} /// <summary>
/// 通过键获取值,如果不存在,则返回传入的默认值
/// </summary>
public T Get<T>(string key, T defaultValue)
{
return dictionary.ContainsKey(key) ? (T) dictionary[key] : defaultValue;
} /// <summary>
/// 设置值,自动保存
/// </summary>
public void Set(string key, object value)
{
if (dictionary.ContainsKey(key))
{
dictionary[key] = value;
}
else
{
dictionary.Add(key, value);
}
Save();
} /// <summary>
/// 保存配置到文件
/// </summary>
public void Save()
{
XmlHelper.Serialize(filePath, dictionary);
} /// <summary>
/// 判断是否包含键
/// </summary>
public bool Contains(string key)
{
return dictionary.ContainsKey(key);
} /// <summary>
/// 析构时保存数据
/// </summary>
~ApplicationSetting()
{
Save();
}
}
}
使用自定义的配置管理器可以控制文件信息,不会出现上述与第三方类库的一些兼容性问题(当然,这种情况比较少)
注意:该配置文件只支持基础类型,不支持复杂类型
【WP8】自定义配置存储类的更多相关文章
- spring-boot 速成(4) 自定义配置
spring-boot 提供了很多默认的配置项,但是开发过程中,总会有一些业务自己的配置项,下面示例了,如何添加一个自定义的配置: 一.写一个自定义配置的类 package com.example.c ...
- .Net 配置文件--继承ConfigurationSection实现自定义处理类处理自定义配置节点
除了使用继承IConfigurationSectionHandler的方法定义处理自定义节点的类,还可以通过继承ConfigurationSection类实现同样效果. 首先说下.Net配置文件中一个 ...
- .Net 配置文件——继承ConfigurationSection实现自定义处理类处理自定义配置节点
除了使用继承IConfigurationSectionHandler的方法定义处理自定义节点的类,还可以通过继承ConfigurationSection类实现同样效果. 首先说下.Net配置文件中一个 ...
- 利用NSUserdefaults来存储自定义的NSObject类及自定义类数组
利用NSUserdefaults来存储自定义的NSObject类及自定义类数组 1.利用NSUserdefaults来存储自定义的NSObject类 利用NSUserdefaults也可以来存储及获取 ...
- Spring 自定义配置类bean
<!-- 引入配置文件 --> <bean id="propertyConfigurer" class="org.springframework.bea ...
- 【spring boot】7.静态资源和拦截器处理 以及继承WebMvcConfigurerAdapter类进行更多自定义配置
开头是鸡蛋,后面全靠编!!! ======================================================== 1.默认静态资源映射路径以及优先顺序 Spring B ...
- C#如何使用和开发自定义配置节
在日常的程序设计中,如何灵活和巧妙地运用配置信息是一个成功的设计师的首要选择.这不仅是为了程序设计得更灵活性和可扩展性,也是为了让你的代码给人以清新的感觉.程序中的配置信息一般放在应用程序的app.c ...
- App.config和Web.config配置文件的自定义配置节点
前言 昨天修改代码发现了一个问题,由于自己要在WCF服务接口中添加了一个方法,那么在相应调用的地方进行更新服务就可以了,不料意外发生了,竟然无法更新.左查右查终于发现了问题.App.config配置文 ...
- rancher2.1.7安装nfs 存储类
NFS存储类不建议作大规模存储,块存储建议采用CEPH(独立安装) NFS只作为外接存储与普通NGINX类的配置文件,业务配置文件建议走配置中心. 增加自定义商店 地址为:https://github ...
随机推荐
- 2. 感知机(Perceptron)基本形式和对偶形式实现
1. 感知机原理(Perceptron) 2. 感知机(Perceptron)基本形式和对偶形式实现 3. 支持向量机(SVM)拉格朗日对偶性(KKT) 4. 支持向量机(SVM)原理 5. 支持向量 ...
- java面向对象(1)
一.方法传不固定值的用法 public void Test(int a,Person ...Persons) { for(Person p:Persons){ ...
- [转]PLSQL Developer软件使用大全
原文地址:https://www.cnblogs.com/lhrbest/p/6493218.html 第一章 PLSQL Developer特性 PL/SQL Developer是一个集成开发环境, ...
- Centos7下Yum安装PHP5.5,5.6,7.0
默认的版本太低了,手动安装有一些麻烦,想采用Yum安装的可以使用下面的方案: 1.检查当前安装的PHP包 yum list installed | grep php 如果有安装的PHP包,先删除他们 ...
- python出现UnicodeEncodeError有可能产生的另一个原因
在使用python中,我们都有可能遇到如下的错误: UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ...
- Spring Cloud Sleuth Zipkin - (2)
在上一节<spring-cloud-sleuth+zipkin追踪服务实现(一)>中,我们使用zipkin-server.provider.consumer三个程序实现了使用http方式进 ...
- python datetime unix时间戳以及字符串时间戳转换
将python的datetime转换为unix时间戳 import time import datetime dtime = datetime.datetime.now() ans_time = ti ...
- 如何在Linux系统上安装字体
libreoffice添加字体 TrueType字体文件的扩展名是.ttf,ttf就是TrueType Font的首字母缩写 一般在 /usr/share/fonts/truetype/ 目录下,这个 ...
- oracle分页查询原理浅析
原因一 oracle默认为每个表生成rowmun,rowid字段,这些字段我们称之为伪列 1 创建测试表 CREATE TABLE TEST( ID NUMBER, NAME VARCHAR2(20) ...
- 目录_Java内存分配(直接内存、堆内存、Unsafel类、内存映射文件)
1.Java直接内存与堆内存-MarchOn 2.Java内存映射文件-MarchOn 3.Java Unsafe的使用-MarchOn 简单总结: 1.内存映射文件 读文件时候一般要两次复制:从磁盘 ...