zoukankan      html  css  js  c++  java
  • Windows Store App之数据存储

      在开发过程中,我们需要将某些数据保存下来,比如一些设置信息以及一些用户主动去保存的数据。待用户下次打开应用时候,再自动加载这些信息。下面将介绍windows8开发中如何存储数据。

    一.本地数据存储

      在wp中我们使用IsolatedStorageSettings进行本地数据存储,在win8中也提供类似的方法进行存储,我们使用ApplicationData.Current.LocalSettings。下面将通过实例进行描述:

      在节目上添加姓名、年龄、性别三个控件,代码如下:

     1 <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
     2         <StackPanel Margin="40,40,0,0">
     3             <StackPanel Orientation="Horizontal" Height="80">
     4                 <TextBlock Text="姓名:" Style="{StaticResource BasicTextStyle}" FontSize="20" VerticalAlignment="Center"/>
     5                 <TextBox x:Name="txtName" Text="" FontSize="24" Width="200" Height="40"/>
     6             </StackPanel>
     7             <StackPanel Orientation="Horizontal" Height="80">
     8                 <TextBlock Text="年龄:" Style="{StaticResource BasicTextStyle}" FontSize="20" VerticalAlignment="Center"/>
     9                 <TextBox x:Name="txtAge" Text="" FontSize="24" Width="200" Height="40"/>
    10             </StackPanel>
    11             <StackPanel Orientation="Horizontal" Height="80">
    12                 <TextBlock Text="性别:" Style="{StaticResource BasicTextStyle}" FontSize="20" VerticalAlignment="Center"/>
    13                 <ComboBox x:Name="cbxSex" Height="40" Width="200" SelectedIndex="1">
    14                     <ComboBoxItem></ComboBoxItem>
    15                     <ComboBoxItem></ComboBoxItem>
    16                 </ComboBox>
    17             </StackPanel>
    18             <StackPanel Orientation="Horizontal">
    19                 <Button Content="保存" Width="100" Height="40" FontSize="16" Click="btnSave_Click"></Button>
    20                 <Button Margin="20,0,0,0" Content="读取" Width="100" Height="40" FontSize="16" Click="btnRead_Click"></Button>
    21                 <Button Margin="20,0,0,0" Content="清空" Width="100" Height="40" FontSize="16" Click="btnClear_Click"></Button>
    22             </StackPanel>
    23         </StackPanel>
    24     </Grid>

    新建类AppDataHelper.cs,引用命名空间using Windows.Storage。我们将读取和保存封装成共通,方便调用。
    保存数据:

     1 /// <summary>
     2 /// 保存数据
     3 /// </summary>
     4 /// <typeparam name="T">数据类型</typeparam>
     5 /// <param name="key"></param>
     6 /// <param name="value"></param>
     7 public static void Save<T>(string key, T value)
     8 {
     9     ApplicationData.Current.LocalSettings.Values[key] = value;
    10 }

    读取数据:

     1 /// <summary>
     2 /// 读取数据
     3 /// </summary>
     4 /// <typeparam name="T">数据类型</typeparam>
     5 /// <param name="key"></param>
     6 /// <returns></returns>
     7 public static T Read<T>(string key)
     8 {
     9     if (ApplicationData.Current.LocalSettings.Values.ContainsKey(key))
    10     {
    11         return (T)ApplicationData.Current.LocalSettings.Values[key];
    12     }
    13     else
    14     {
    15         return default(T);
    16     }
    17 }

    删除数据:

    1  /// <summary>
    2 /// 移除数据
    3 /// </summary>
    4 /// <param name="key"></param>
    5 /// <returns>成功true/失败false</returns>
    6 public static bool Remove(string key)
    7 {
    8     return ApplicationData.Current.LocalSettings.Values.Remove(key);
    9 }

    我们只要在需要存储或者读取数据的地方进行调用,就可以了。

     1  private void btnSave_Click(object sender, RoutedEventArgs e)
     2 {
     3     AppDataHelper.Save<string>("name", txtName.Text.Trim());
     4     AppDataHelper.Save<int>("age", int.Parse(txtAge.Text.Trim()));
     5     AppDataHelper.Save<int>("sex", cbxSex.SelectedIndex);
     6 }
     7 private void btnRead_Click(object sender, RoutedEventArgs e)
     8 {
     9     txtName.Text = AppDataHelper.Read<string>("name");
    10     txtAge.Text = AppDataHelper.Read<int>("age").ToString();
    11     cbxSex.SelectedIndex = AppDataHelper.Read<int>("sex");
    12 }

    那么我们保存的数据保存到哪里去了呢?我们应该如何找到他们,别急,我们下面开始找保持的数据。
    打开C:\Users\<user_name>\AppData\Local\Packages\<package>\Settings\settings.dat, user_name对应当前登录的用户名,packpage对应此应用的唯一标识,在Package.appxmanifest中我们可以找到它:

    此文件为.dat后缀,我们需要用注册表工具打开它,开始->运行(win+R键),输入Regedit,在打开的窗口里面选择 HKEY_LOCAL_MACHINE,

     

    然后选择文件->加载配置单元,选择settings.dat文件,打开填入项名称,确定之后可以看到保存的数据会显示在其中。

     

    双击name,打开,我们可以看到存储的数据值。

     那么我们是否能像wp那样存储一个对象到本地存储呢,答案是否定的。win8中只能存储一些简单类型,如int、bool、string等

    下面有一个Person对象:

     1 [DataContract]
     2     public class Person
     3     {
     4         [DataMember]
     5         public string Name { get; set; }
     6         [DataMember]
     7         public int Age { get; set; }
     8         [DataMember]
     9         public int Sex { get; set; }
    10     }

    进行存储:

    1 Person person = new Person()
    2  {
    3      Name = txtName.Text.Trim(),
    4      Age = int.Parse(txtAge.Text.Trim()),
    5      Sex = cbxSex.SelectedIndex
    6  };
    7 AppDataHelper.Save<Person>("person", person);

    此时会报错,提示不支持此类型存储。

    那么我们应该如何存储一个对象呢?下面我们将介绍文件存储。

    二.文件存储

      对于那些比较复杂的数据类型,我们需要将其存储为文件的形式存储在应用中。StorageFile的存储,以文件的形式进行存储存入数据。

    新建一个类,LocalFileHelper.cs

    存储文件:

     1 /// <summary> 
     2 /// 存储数据/// </summary>
     3 /// <typeparam name="T">数据类型</typeparam>
     4 /// <param name="fileName">文件名称</param>
     5 /// <param name="data">数据</param>
     6 /// <returns></returns>
     7 public async static Task Save<T>(string fileName, T data)
     8 {
     9     //取得当前程序存放数据的目录  
    10     StorageFolder folder = Windows.Storage.ApplicationData.Current.LocalFolder;
    11     //创建文件,如果文件存在就覆盖  
    12     StorageFile file = await folder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
    13     using (Stream newFileStream = await file.OpenStreamForWriteAsync())
    14     {
    15         DataContractSerializer ser = new DataContractSerializer(typeof(T));
    16         ser.WriteObject(newFileStream, data);
    17         newFileStream.Dispose();
    18     }
    19 }

    读取文件:

     1 /// <summary>
     2 /// 读取数据
     3 /// </summary>
     4 /// <typeparam name="T">数据类型</typeparam>
     5 /// <param name="fileName">文件名称</param>
     6 /// <returns>数据</returns>
     7 public async static Task<T> Read<T>(string fileName)
     8 {
     9     T t = default(T);
    10     try
    11     {
    12         StorageFolder folder = Windows.Storage.ApplicationData.Current.LocalFolder;
    13         StorageFile file = await folder.GetFileAsync(fileName);
    14         if (file == null)
    15             return t;
    16         Stream newFileStream = await file.OpenStreamForReadAsync();
    17         DataContractSerializer ser = new DataContractSerializer(typeof(T));
    18         t = (T)ser.ReadObject(newFileStream);
    19         newFileStream.Dispose();
    20         return t;
    21     }
    22     catch (Exception)
    23     {
    24         return t;
    25     }
    26 }

    删除文件:

     1 /// <summary>
     2 /// 删除文件
     3 /// </summary>
     4 /// <param name="fileName">文件名称</param>
     5 /// <returns>成功true/失败false</returns>
     6 public async static Task<bool> Delete(string fileName)
     7 {
     8     StorageFolder folder = Windows.Storage.ApplicationData.Current.LocalFolder;
     9     StorageFile file = await folder.GetFileAsync(fileName);
    10     if (file != null)
    11     {
    12         try
    13         {
    14             await file.DeleteAsync();
    15         }
    16         catch (Exception)
    17         {
    18             return false;
    19         }
    20     }
    21     return true;
    22 }

    使用方法:

     1 Person person = new Person()
     2 {
     3        Name = txtName.Text.Trim(),
     4         Age = int.Parse(txtAge.Text.Trim()),
     5         Sex = cbxSex.SelectedIndex
     6 };
     7 
     8 await LocalFileHelper.Save<Person>("person.xml", person);
     9 
    10 List<Person> list = new List<Person>();
    11 list.Add(person);
    12 list.Add(person);
    13 await LocalFileHelper.Save<List<Person>>("personList.xml", list);
    14 
    15 
    16 Person newPerson = await LocalFileHelper.Read<Person>("person.xml");
    17 List<Person> personList = await LocalFileHelper.Read<List<Person>>("personList.xml");

    文件在哪里?

    同样我们打开C:\Users\user_name\AppData\Local\Packages\package\LocalState文件夹,下面就有我们保持的文件,打开文件,保存文件的内容格式为xml:

    <Person xmlns="http://schemas.datacontract.org/2004/07/StorageSample" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Age>27</Age><Name>BetterChaner</Name><Sex>0</Sex></Person>

    三.使用Sqlite进行数据存储

      Sqlite现已提供对Windows RT和Windows 8 Metro应用的支持.

    首先,在工具,选择扩展与更新中,选择联机,在搜索框内输入sqlite,找到SQLite for Window Runtime,下载安装。

    安装完成之后重启VS,右击项目添加引用,选择Windows->扩展,找到Mircosoft visual c++ runtime package和sqlite for windows runtime,打勾,确定。

    由于目前Sqlite不支持AnyCPU,所以我们将项目改成X64,右击解决方案,属性,修改之。

    然后右击引用,选择管理Nuget程序包,联机搜索sqlite-net,下载安装。

    我们发现项目工程中多了2个类文件,SQLite.cs和SQLiteAsync.cs

    基本操作:

     1 //创建数据库
     2 string dbRootPath = Windows.Storage.ApplicationData.Current.LocalFolder.Path;
     3 SQLiteConnection db = new SQLiteConnection(Path.Combine(dbRootPath, "myApp.sqlite"));
     4 
     5 //创建表
     6 db.CreateTable<Person>();
     7 
     8 //插入一条数据
     9 db.Insert(new Person() { Name = "BetterChaner", Age = 27, Sex = 1 });
    10 
    11 //插入多条数据
    12 List<Person> list = new List<Person>();
    13 list.Add(new Person() { Name = "Zhangsan", Age = 27, Sex = 1 });
    14 list.Add(new Person() { Name = "Lisi", Age = 32, Sex = 0 });
    15 list.Add(new Person() { Name = "Wangwu", Age = 24, Sex = 1 });
    16 db.InsertAll(list);
    17 
    18 //查询数据
    19 List<Person> list2 = db.Query<Person>("select * from Person");
    20 
    21 //更新数据
    22 SQLiteCommand cmd = db.CreateCommand("update Person set Age=21 where Name='Lisi'");
    23 cmd.ExecuteNonQuery();
    24 
    25 //删除一条数据
    26 db.Delete(new Person() { Name = "Zhangsan", Age = 27, Sex = 1 });
    27 //删除全部数据
    28 db.DeleteAll<Person>();

    数据存储的位置为:C:\Users\<user_name>\AppData\Local\Packages\<package>\LocalState\文件夹下的myApp.sqlite

    四.SqlCE

      有了Sqilte,SqlCE不太经常会用到了,在这里就不写出实例了,与wp中类似。

    小结

    以上为windows store app开发中可以使用的几种存储数据的方式,可以根据数据大小、作用以及类型选择应该使用哪一种存储方式。

    源码下载

    代码之美
  • 相关阅读:
    sql当前行数据和之前行数据相加减循环处理
    Sql 查询库、表、列名的语句
    sql 特殊字符替换
    pandas 篇
    JAVA学习--面向对象的特征二:继承性
    JAVA学习--super使用
    JAVA学习--方法的参数传递
    JAVA学习--可变个数的形参的方法
    JAVA学习--面向对象思想的落地法则
    JAVA学习--方法的重载
  • 原文地址:https://www.cnblogs.com/betterchaner/p/2915504.html
Copyright © 2011-2022 走看看