数据序列化程序已针对Windows Metro更新(译文)
By S.F.
本文链接 https://www.kyfws.com/news/data-serializer-updated-for-windows-metro/
版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
- 3 分钟阅读 - 1074 个词 阅读量 0数据序列化程序已针对Windows Metro更新(译文)
原文地址:https://www.codeproject.com/Articles/367042/Data-Serializer-updated-for-Windows-Metro
原文作者:Joel Ivory Johnson
译文由本站翻译
前言
Windows Metro的数据序列化程序更新.
大约一年前,我共享了一个简单的实用程序类,用于在Windows Phone 7上保存可序列化的数据.我刚刚更新了Windows 8 Metro的组件.通过使用条件编译器指令,它仍然保留与Windows Phone 7的兼容性.在Windows Phone 7上,我更改了类,使其为静态(因此无需实例化). 对于Metro,方法是异步的.为了保存,可以传递一个动作,一旦保存操作完成,该动作将被调用.加载数据时,您将要传递一个操作,该操作将接收已加载的数据,以及一个异常参数,如果无法加载数据,则将填充该参数. 作为代码工作方式的一个示例(及其用法所依赖的平台差异),这里是我使用该程序的程序中的一种方法.该程序可在Windows Phone 7和Windows Metro上编译.
public void LoadAccess()
{
#if SILVERLIGHT
AccessInfo = DataSaver<AccessInfo>.LoadMyData("_accessToken.xml");
#endif
#if NETFX_CORE
DataSaver<AccessInfo>.LoadDataAsync("_accessToken.xml", (info, exc)=>
{
if (info != null)
{
this.AccessInfo = info;
}
});
#endif
}
public void SaveAccessToken()
{
if (this.AccessInfo != null)
{
#if NETFX_CORE
DataSaver<AccessInfo>.SaveMyDataAsync(this.AccessInfo, "_accessToken.xml");
#endif
#if SILVERLIGHT
DataSaver<AccessInfo>.SaveMyData(AccessInfo, "_accessToken.xml");
#endif
}
}
如果您从未见过#if/#endif指令,则该指令实际上是根据某种条件有条件地注释掉代码段的.在这种情况下,条件是要定义某些编译器常量.将为各种项目类型自动创建一些常量.如果创建Windows Phone项目,则将定义" WINDOWS_PHONE"和" SILVERLIGHT"常量.对于Windows 8 Metro项目,定义了NETFX_CORE常量.当您在Visual Studio IDE中查看代码时,由于有条件的编译语句,它将使所有将被忽略的代码均灰显. 以下是序列化器的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.IO;
#if SILVERLIGHT
using System.IO.IsolatedStorage;
#endif
#if NETFX_CORE
using System.Threading.Tasks;
using Windows.Storage;
using Windows.Storage.Streams;
#endif
namespace J2i.Net.Utility
{
public class DataSaver<MyDataType>
{
static List<Type> _knownTypeList = new List<Type>();
public static List KnownTypeList
{
get
{
return _knownTypeList;
}
}
#if SILVERLIGHT
private static IsolatedStorageFile _isoFile;
static IsolatedStorageFile IsoFile
{
get
{
if (_isoFile == null)
_isoFile = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication();
return _isoFile;
}
}
public static void SaveMyData(MyDataType sourceData, String targetFileName)
{
try
{
using (var targetFile = IsoFile.CreateFile(targetFileName))
{
var d = new DataContractSerializer(typeof(MyDataType), KnownTypeList);
d.WriteObject(targetFile, sourceData);
}
}
catch (Exception )
{
IsoFile.DeleteFile(targetFileName);
}
}
public static MyDataType LoadMyData(string sourceName)
{
MyDataType retVal = default(MyDataType);
if (IsoFile.FileExists(sourceName))
using (var sourceStream = IsoFile.OpenFile(sourceName, FileMode.Open))
{
var d = new DataContractSerializer(typeof(MyDataType), KnownTypeList);
retVal = (MyDataType)d.ReadObject(sourceStream);
}
return retVal;
}
#endif
public DataSaver()
{
}
#if NETFX_CORE
public static async void SaveMyDataAsync(
MyDataType sourceData,
String targetFileName,
Action<MyDataType,String, Exception> OnSaved = null)
{
try
{
StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(
targetFileName, CreationCollisionOption.ReplaceExisting
);
IRandomAccessStream raStream = await file.OpenAsync(FileAccessMode.ReadWrite);
IOutputStream outStream = raStream.GetOutputStreamAt(0);
DataContractSerializer serializer = new DataContractSerializer(typeof(MyDataType), KnownTypeList);
serializer.WriteObject(outStream.AsStreamForWrite(), sourceData);
await outStream.FlushAsync();
if(OnSaved!=null)
OnSaved(sourceData, targetFileName, null);
}
catch (Exception exc)
{
if (OnSaved != null)
{
OnSaved(sourceData, targetFileName, exc);
}
}
}
public static async void LoadDataAsync(string fileName,
Action<MyDataType, Exception> loadAction)
{
if (loadAction == null)
return;
try
{
StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync(fileName);
if (file == null) return;
IInputStream inStream = await file.OpenSequentialReadAsync();
// Deserialize the Session State.
DataContractSerializer serializer =
new DataContractSerializer(typeof(MyDataType), KnownTypeList);
MyDataType data = (MyDataType)serializer.ReadObject(inStream.AsStreamForRead());
loadAction(data, null);
}
catch (Exception e)
{
loadAction(default(MyDataType), e);
}
}
#endif
}
}
许可
本文以及所有相关的源代码和文件均已获得The Code Project Open License (CPOL)的许可。
C# Dev Intermediate Windows-Phone-7 Metro-design 新闻 翻译