65.9K
CodeProject 正在变化。 阅读更多。
Home

如何在 Windows Phone 8.1 中加载和读取本地存储数据

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.43/5 (6投票s)

2015 年 6 月 9 日

CPOL

4分钟阅读

viewsIcon

25456

downloadIcon

293

Windows Phone 8.1 RT Microsoft 在 Windows Phone 8.1 中引入了许多新功能和更改。Isolated Storage(隔离存储)是其中一项关键功能,它在 Windows Phone 8.1 中发生了彻底的改变。

引言

首先,我想说我在这里要描述的并非凭空而来,网上有很多关于如何在 Windows Phone 8.1 的隔离存储中保存数据的文章,但我当时想要实现的功能并不容易找到,我不得不找到一些机制来实现它。

我了解到,在 Windows Phone 8.1 RT 中,Microsoft 在 Windows Phone 8.1 中引入了许多新功能和更改。Isolated Storage(隔离存储)是其中一项关键功能,它在 Windows Phone 8.1 中发生了彻底的改变。

在本文中,我将描述发生了哪些变化以及如何在 Windows Phone 8.1 RT 中实现相同的功能。

背景

在我之前的 Windows Phone 8 应用中,我有一个名为 GameScore 的对象,其中包含游戏分数,随着游戏的进展并达到不同的关卡,它会保存该分数。我们将新的 GameScore 对象保存在 IsolatedStorage 中。

但是,当我尝试在 Windows Phone 8.1 RT 中实现相同的概念时,我感到惊讶,因为整个概念都改变了,我不得不找到一种不同的机制来实现。本文将详细介绍如何实现这一点。

下面是我将在 Windows Phone 8.1 中实现的功能的视觉表示。

Using the Code

请下载源代码并运行,以便更好地理解本文。

首先,让我告诉你们我在 Windows Phone 8 中做了什么。

在 Windows Phone 8 中,我有一个类

public class GameScore
{
    public string Date {get;set;}
    public int Score {get;set;} 
    public string Time {get;set;}     
}

游戏结束后,我们需要将游戏分数保存到 IsolatedStorage 中的 GameScore 对象中。通过使用 backgroundtask,我们在此处实现了这一点,这是代码……

private void SaveGameScoreAsync(GameScore gameScore)
{
    GameScore DataLists = gameScore;
    IsolatedStorageSettings localStorage = IsolatedStorageSettings.ApplicationSettings;

    if (!localStorage.Contains("GameData"))
    {
        IsoScoresSettings.Add(DataLists);
        localStorage.Add("GameData", IsoScoresSettings);
    }
    else
    {
        List<GameScore> GameScoresCollections = new List<GameScore>();
        GameScoresCollections = IsolatedStorageSettings.ApplicationSettings["GameData"]
                                                                  as List<GameScore>;
              
        GameScoresCollections.Add(DataLists);
        localStorage["GameData"] = GameScoresCollections;
    }

    localStorage.Save();
}

因此,通过这种机制,我们可以将 GameScore 保存到 IsolatedStorage 中,当然,在 Window Phone 8 中有很多可用的机制,但这是开发人员保存一些设置到 IsolatedStorage 中最常用的方法,不过这也不是本文的讨论重点。

在 Windows Phone 8.1 RT 中,我们可以使用 LocalFolder 来存储手机中的数据,而不是使用 IsolatedStorage

我将使用 ApplicationData.Current.LocalFolderDataContractSerializer 来实现与 Windows Phone 8 相同的功能。

正如您在 MainPage.xaml.cs 中看到的,我写了

private const string JSONFILENAME = "data.json";

这个 data.json 将是一个我们将写入并保存游戏相关数据的文件的名称。

然后,我将创建一个 GameScore 类,类似于 Windows Phone 8。

public class GameScore
{
    public string Id {get;set;}
    public int Score {get;set;}     
    public string Time {get;set;}
}

让我们在 MainPage.xaml.cs 中创建一个 GameScore 对象。

private List<GameScore> BuildGameScore()
{
    var myScore = new List< GameScore >();
    myScore.Add(new GameScore () { Id = "1", Score = 100, Time = "220"});
    myScore.Add(new GameScore () { Id = "2", Score = 200, Time = "500"});
    myScore.Add(new GameScore () { Id = "3", Score = 300, Time = "880"});
    myScore.Add(new GameScore () { Id = "4", Score = 400, Time = "250"});

    return myScore;
}

那么我现在需要做什么?我需要编写两个方法,一个方法将数据写入 data.json 文件,另一个方法读取数据。

Write 方法是 writeJsonAsync,读取方法是 readJsonAsync

// Write the Json string in the JSONFILENAME.
private async Task writeJsonAsync()
{   
   var myGameScore = BuildGameScore();
   var serializer = new DataContractJsonSerializer(typeof(List<GameScore>));

   using (var stream = await ApplicationData.Current.LocalFolder.OpenStreamForWriteAsync(
                       JSONFILENAME,
                       CreationCollisionOption.ReplaceExisting))
   {
       serializer.WriteObject(stream, myGameScore);
   }
   resultTextBlock.Text = "Write succeeded";
}

// Read the Json string stored in the JSONFILENAME.
 private async Task readJsonAsync()
 {
     string content = String.Empty;
     List<GameScore> ListGameScore = new List<GameScore>();

     var myStream = await  ApplicationData.Current.LocalFolder.OpenStreamForReadAsync(JSONFILENAME);

     using (StreamReader reader = new StreamReader(myStream))
     {
         content = await reader.ReadToEndAsync();
     }
     
     resultTextBlock.Text = content;
}

现在,正如您所看到的,XAML 中有两个 Button Clicks 事件

  • 读取
  • Write

现在,我在代码隐藏中实现了两个按钮的点击事件。

private async void readButton_Click(object sender, RoutedEventArgs e)
{
    await readJsonAsync();
}

private async void writeButton_Click(object sender, RoutedEventArgs e)
{
     await writeJsonAsync();
}

如果我运行应用程序,首先点击 Write,UI 中会显示一条消息

Write succeeded

现在我们的任务是测试这一点,点击 Read 按钮。

存储在 data.json 中的数据将显示在 UI 中。

因此,我们已经完成了主要任务,我们已经将数据写入文件并完美地读取了它。

但这还不是我们的目标,我们希望将数据写入文件并更新文件而不丢失之前的数据。

为了实现这一点,我们首先需要在 GameScore 类中编写一个方法来完成我们的工作。

public static List<GameScore> ConvertToGameScoreItems(string json)
{
    List<GameScore> rsp = new List<GameScore>();
    try
    {
        DataContractJsonSerializer serializer = new  
                                     DataContractJsonSerializer(typeof(List<GameScore>));
        using (MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json)))
        {
            rsp = serializer.ReadObject(ms) as List<GameScore>;
        }
    }
    catch(Exception ex) { }

    return rsp;
}

那么这个 jsonserializer 是做什么的?它将读取 json 文件中存储的所有数据,并将其转换为 List<GameScore> 对象。这样,我们就不会丢失我们的数据。

但是如何使用它呢?在我们的 MainPage.xaml.cs 中,我们将再写一个任务,并将其分配给另一个按钮的 Button_Click event - Write-Read

private async Task AddEntryIntoJsonAsync()
{
     string content = String.Empty;
     List<GameScore> ListGameScore = new List<GameScore>();

     var myStream = await ApplicationData.Current.LocalFolder.OpenStreamForReadAsync(JSONFILENAME);

     using (StreamReader reader = new StreamReader(myStream))
     {
         content = await reader.ReadToEndAsync();
     }
     
     ListGameScore = GameScore.ConvertToGameScoreItems(content);
   
     //Now add one more Entry.
     ListGameScore.Add(new GameScore() { Id = "11", Score = 545, Time = "874"});

     var serializer = new DataContractJsonSerializer(typeof(List<GameScore>));

     using (var stream = await ApplicationData.Current.LocalFolder.OpenStreamForWriteAsync(
                         JSONFILENAME,
                         CreationCollisionOption.ReplaceExisting))
     {
          serializer.WriteObject(stream, ListGameScore);
     }

     myStream = await ApplicationData.Current.LocalFolder.OpenStreamForReadAsync(JSONFILENAME);

     using (StreamReader reader = new StreamReader(myStream))
     {
         content = await reader.ReadToEndAsync();
     }

     resultTextBlock.Text = content;
}

并将其分配给另一个 Button_Click 事件。

 private async void readWriteButton_Click(object sender, RoutedEventArgs e)
 {
     await AddEntryIntoJsonAsync();
 }

因此,通过在 GameScore 类中实现的 ConvertToGameScoreItems,我实现了我在 Windows Phone 8 中所做的工作。

此对象可用于在 UI 中显示游戏分数。但这超出了本文的范围。

摘要

在本文中,我展示了如何使用 Json 和序列化器来保存、加载和更新 json 文件。

我希望您喜欢这篇文章,在下一篇文章中,我计划专注于 Windows Phone 8.1 的一些新功能,并提供更多实际使用示例。

历史

这是我的初稿,如果有任何拼写错误或错误,请在评论区回复,我一定会更新这篇文章。

© . All rights reserved.