WP8的文件和存储

来源:互联网 发布:淘宝直播没平台网址 编辑:程序博客网 时间:2024/05/16 06:54

内容预告:

  • 特殊的文件夹(Shared/Media,Shared/ShellContent,Shared/Transfer)
  • 用ISET浏览本地文件夹
  • 后台文件传输
  • 使用SD存储卡

但不包括:

  • 本地数据库(基于LINQ的sqlce)
  • SQLite

本地数据存储概览:打包管理器把所有的App放到"安装文件夹",App存储数据到"本地文件夹"。

定位存储位置的不同方式:

WP8文件存储的备选方案:三种方式

复制代码
// WP7.1 IsolatedStorage APIsvar isf = IsolatedStorageFile.GetUserStoreForApplication();IsolatedStorageFileStream fs = new IsolatedStorageFileStream("CaptainsLog.store", FileMode.Open, isf));...// WP8 Storage APIs using URIStorageFile storageFile = await Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(                        new Uri("ms-appdata:///local/CaptainsLog.store "));...// WP8 Storage APIsWindows.Storage.StorageFolder localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;Windows.Storage.StorageFile storageFile = await localFolder.GetFileAsync("CaptainsLog.store");
复制代码

用WP7.1的方式:

IsolatedStorage类在System.IO.IsolatedStorage命名空间里:

  • IsolatedStorage,在独立存储区表达文件和文件夹
  • IsolatedFileStream,在IsolatedStorage中暴露一个文件流到文件存储。
  • IsolatedStorageSettings,以键值对(Dictionary<TKey,TValue>)方式存储。

保存数据:

复制代码
private void saveGameToIsolatedStorage(string message){  using (IsolatedStorageFile isf =         IsolatedStorageFile.GetUserStoreForApplication())  {    using (IsolatedStorageFileStream rawStream = isf.CreateFile("MyFile.store"))    {       StreamWriter writer = new StreamWriter(rawStream);       writer.WriteLine(message); // save the message       writer.Close();    }  }}
复制代码

读取数据:

复制代码
private void saveGameToIsolatedStorage(string message){  using (IsolatedStorageFile isf =         IsolatedStorageFile.GetUserStoreForApplication())  {    using (IsolatedStorageFileStream rawStream = isf.CreateFile("MyFile.store"))    {       StreamWriter writer = new StreamWriter(rawStream);       writer.WriteLine(message); // save the message       writer.Close();    }  }}
复制代码

保存键值对数据:记着在最后调用Save函数保存。

复制代码
void saveString(string message, string name){   IsolatedStorageSettings.ApplicationSettings[name] =     message;    IsolatedStorageSettings.ApplicationSettings.Save();}
复制代码

读取键值对数据:记着要先检查是否有这个键,否则要抛异常。

复制代码
string loadString(string name){  if (IsolatedStorageSettings.ApplicationSettings.Contains(name))  {      return (string)           IsolatedStorageSettings.ApplicationSettings[name];    }    else        return null;}
复制代码

WinPRT的存储方式:在Windows.Storage命名空间下:

  • StorageFolder
  • StorageFile
  • 不支持ApplicationData.LocalSettings,只能用IsolatedStorageSettings或自定义文件

用StorageFolder保存数据:

复制代码
private async void saveGameToIsolatedStorage(string message){     // Get a reference to the Local Folder     Windows.Storage.StorageFolder localFolder =          Windows.Storage.ApplicationData.Current.LocalFolder;    // Create the file in the local folder, or if it already exists, just open it    Windows.Storage.StorageFile storageFile =                 await localFolder.CreateFileAsync("Myfile.store",                           CreationCollisionOption.OpenIfExists);    Stream writeStream = await storageFile.OpenStreamForWriteAsync();    using (StreamWriter writer = new StreamWriter(writeStream))    {        await writer.WriteAsync(logData);    }}
复制代码

读取数据:

复制代码
private async void saveGameToIsolatedStorage(string message){     // Get a reference to the Local Folder     Windows.Storage.StorageFolder localFolder =          Windows.Storage.ApplicationData.Current.LocalFolder;    // Create the file in the local folder, or if it already exists, just open it    Windows.Storage.StorageFile storageFile =                 await localFolder.CreateFileAsync("Myfile.store",                           CreationCollisionOption.OpenIfExists);    Stream writeStream = await storageFile.OpenStreamForWriteAsync();    using (StreamWriter writer = new StreamWriter(writeStream))    {        await writer.WriteAsync(logData);    }}
复制代码

ms-appdata:/// or ms-appx:/// 保存文件:

复制代码
// There's no FileExists method in WinRT, so have to try to open it and catch exception instead  StorageFile storageFile = null;  bool fileExists = false;  try    {    // Try to open file using URI    storageFile = await StorageFile.GetFileFromApplicationUriAsync(                    new Uri("ms-appdata:///local/Myfile.store"));    fileExists = true;  }  catch (FileNotFoundException)  {    fileExists = false;  }  if (!fileExists)   {    await ApplicationData.Current.LocalFolder.CreateFileAsync("Myfile.store",CreationCollisionOption.FailIfExists);   }  ...
复制代码

Windows 8 与 Windows Phone 8 兼容性:

  • WP8下所有的数据存储用LocalFolder(等效于WP7.1下的IsolatedStorage)
  • 不支持漫游数据:ApplicationData.Current.RoamingFolder
  • 临时数据:ApplicationData.Current.RoamingFolder
  • 本地键值对:ApplicationData.Current.LocalSettings
  • 漫游键值对:ApplicationData.Current.RoamingSettings
  • 在Windows8下,可以在用下以代码在XAML元素里加载AppPackages里的图片:
    RecipeImage.Source = new System.Windows.Media.Imaging.BitmapImage(           new Uri(@"ms-appx:///Images/french/French_1_600_C.jpg", UriKind.RelativeOrAbsolute));

    在Windows Phone8下,不支持这个URI的语法。只能像Windows Phone7.1那样:

    RecipeImage.Source = new System.Windows.Media.Imaging.BitmapImage("/Images/french/French_1_600_C.jpg");

     

本地文件夹:所有读写的I/O操作仅限于本地文件夹(Local Folder)

 保留文件夹:除一般的存储之外,本地文件夹还用于一些特殊场景:

  • Shared\Media,显示后台播放音乐的艺术家图片。
  • Shared\ShellContent,Tiles的背景图片可以存在这。
  • Shared\Transfer,后台文件传输的存储区域。


数据的序列化:有关数据的持久化

在启动时,从独立存储反序列化。
休眠和墓碑时,序列化并持久存储到独立存储。
激活时,从独立存储反序列化。
终止时,序列化并持久存储到独立存储。

为什么序列化:

序列化可以让内存中的数据集持久存储到文件中,反序列化则可以将文件中的数据读取出来。可以用以下方式做序列化:

  • XmlSerializer
  • DataContractSerializer
  • DataContractJsonSerializer
  • json.net等第三方工具

 DataContractSerializer做序列化:

复制代码
public class MyDataSerializer<TheDataType>    {        public static async Task SaveObjectsAsync(TheDataType sourceData, String targetFileName)        {            StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(                targetFileName, CreationCollisionOption.ReplaceExisting);            var outStream = await file.OpenStreamForWriteAsync();            DataContractSerializer serializer = new DataContractSerializer(typeof(TheDataType));            serializer.WriteObject(outStream, sourceData);            await outStream.FlushAsync();            outStream.Close();        }        ...    }
复制代码

用的时候:

List<MyDataObjects> myObjects = ...     await MyDataSerializer<List<MyDataObjects>>.SaveObjectsAsync(myObjects, "MySerializedObjects.xml");

DataContractSerializer反序列化:

复制代码
public class MyDataSerializer<TheDataType>    {        public static async Task<TheDataType> RestoreObjectsAsync(string fileName)        {            StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync(fileName);            var inStream = await file.OpenStreamForReadAsync();            // Deserialize the objects.             DataContractSerializer serializer =                new DataContractSerializer(typeof(TheDataType));            TheDataType data = (TheDataType)serializer.ReadObject(inStream);            inStream.Close();            return data;        }        ...    }
复制代码

用的时候:

List<MyDataObjects> myObjects    = await MyDataSerializer<List<MyDataObjects>>.RestoreObjectsAsync("MySerializedObjects.xml");

SD卡存储:必须先在application manifest文件中钩选ID_CAP_REMOVABLE_STORAGE,但不能写文件进去,且只能读取APP注册了的文件关联类型。

声明文件类型关联:WMAppManifest.xml文件中,在Extensions下添加一个FileTypeAssociation元素,Extensions必须紧张着Token元素,且FiteType的ContentType属性是必须的。

复制代码
<Extensions>  <FileTypeAssociation Name=“foo" TaskID="_default" NavUriFragment="fileToken=%s">    <SupportedFileTypes>      <FileType ContentType="application/foo">.foo</FileType>    </SupportedFileTypes>  </FileTypeAssociation></Extensions>
复制代码

读取SD卡的API:

 


配额管理:Windows Phone里没有配额。应用自己必须小心使用空间。除非需要,否则不要使用存储空间,而且要告诉用户用了多少。定时删除不用的内容,并考虑同步或归档数据到云服务上。

同步和线程:当状态信息是复杂的对象时,可以简单地序列化这个对象,序列化可能会比较慢。将加载和保存数据放在一个单独的线程里,以保证程序的可响应性。

原创粉丝点击