Window Phone 8.1: путаница с расположением файла и записью данных

Я пытаюсь читать и записывать данные с помощью файла json. Я создал какой-то класс.

public class SimpleTask{...}
public class DayTask{...}
public class DataModel
{
    ...
    private async Task GetSimpleTaskAsync()
    {
        if (_daytask.Count != 0)
            return;
        string fileName = "a.json";
        Uri appUri = new Uri("ms-appx:///"+ fileName);
        StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(appUri);
        string jsonText = await FileIO.ReadTextAsync(file);
        JsonObject jsonObject = JsonObject.Parse(jsonText);
        JsonArray jsonArray = jsonObject["DayTasks"].GetArray();
        foreach (JsonValue daytaskValue in jsonArray)
        {
            JsonObject daytaskObject = daytaskValue.GetObject();
            ObservableCollection<SimpleTask> simpletask = new ObservableCollection<SimpleTask>();
            foreach (JsonValue simpletaskValue in daytaskObject["Tasks"].GetArray())
            {
                JsonObject simpletaskObject = simpletaskValue.GetObject();
                simpletask.Add(new SimpleTask(   simpletaskObject["StartTime"].GetString(),
                                                 simpletaskObject["EndTime"].GetString(), 
                                                 simpletaskObject["Description"].GetString()));
            }
            DayTask daytask = new DayTask(daytaskObject["Day"].GetString(),simpletask);

            this.DayTasks.Add(daytask);
        }
    }


}

Как видите, у меня есть метод, который получает данные из файла .json. Я создал файл .json: введите здесь описание изображения

В MainPage.xaml.cs есть метод, который вызывает метод GetDayTaskAysnc() и извлекает данные:

private async void ReadData1(object sender, TappedRoutedEventArgs e)
    {
        string test = String.Empty;
        var daytask = await DataModel.GetDayTaskAsync();
        foreach (var tasks in daytask)
        {
            test += String.Format("Day:{0}:\n", tasks.Day);
            foreach (var simpletask in tasks.Tasks)
            {
                test += String.Format("\tStart Time: {0}\n", simpletask.StartTime);
                test += String.Format("\tEnd Time: {0}\n", simpletask.EndTime);
                test += String.Format("\tDescription Time: {0}\n", simpletask.Description);
            }
        }
        TextBlock.Text = test;
}

Он работал нормально! Но я хочу записать данные в тот же файл, поэтому я добавил данные хардкорным способом:

private List<DayTask> creatList()
    {
        List<DayTask> DayTasks = new List<DayTask>();
        ObservableCollection<SimpleTask> simpletask1 = new ObservableCollection<SimpleTask>();
        simpletask1.Add(new SimpleTask("6AM","7AM","Breakfast"));
        simpletask1.Add(new SimpleTask("8AM", "9AM", "Game"));
        ObservableCollection<SimpleTask> simpletask2 = new ObservableCollection<SimpleTask>();
        simpletask2.Add(new SimpleTask("6AM", "7AM", "Sleep"));
        simpletask2.Add(new SimpleTask("8AM", "9AM", "School"));
        DayTasks.Add(new DayTask ("3/8/2014",simpletask1));
        DayTasks.Add(new DayTask("4/8/2014", simpletask2));
        return DayTasks;
    }
    private async void WriteData(object sender, TappedRoutedEventArgs e)
    {
        string json = "a.json";
        List<DayTask> daytasks = creatList();
        var serializer = new DataContractJsonSerializer(typeof(List<DayTask>));
        var stream = await ApplicationData.Current.LocalFolder.OpenStreamForWriteAsync(json, CreationCollisionOption.ReplaceExisting);
        using (stream)
        {
            serializer.WriteObject(stream, daytasks);
        }

        TextBlock.Text = "Write to Json file succeeded";
    }

Когда я запустил свое приложение с эмулятором оконного телефона, во-первых, оно записало в файл. Затем я нажал кнопку чтения данных, чтобы убедиться, что данные записаны правильно, эмулятор показал данные из файла .json без изменения методом WriteData(). Я продолжил создание второго метода чтения данных:

private async void ReadData2(object sender, TappedRoutedEventArgs e)
    {
        string test = String.Empty;
        string json = "a.json";
        string content = String.Empty;
        List<DayTask> mytasks = new List<DayTask>();
        var deserializer = new DataContractJsonSerializer(typeof(List<DayTask>));
        var stream = await ApplicationData.Current.LocalFolder.OpenStreamForReadAsync(json);
        using (stream)
        {
            mytasks = (List<DayTask>)deserializer.ReadObject(stream);
        }
        foreach (var tasks in mytasks)
        {
            test += String.Format("Day:{0}:\n", tasks.Day);
            foreach (var simpletask in tasks.Tasks)
            {
                test += String.Format("\tStart Time: {0}\n", simpletask.StartTime);
                test += String.Format("\tEnd Time: {0}\n", simpletask.EndTime);
                test += String.Format("\tDescription Time: {0}\n", simpletask.Description);
            }
        }
        TextBlock.Text = test;
    }

Я развернул свое приложение несколько раз, и вот мой результат:

  1. ReadData2(): 'System.IO.FileNotFoundException'
  2. WriteData() -> ReadData1(): были показаны данные из a.json
  3. WriteData() -> ReadData2(): были показаны данные из creatList()
  4. WriteData() -> ReadData1(): были показаны данные из a.json -> ReadData2(): были показаны данные из creatList()

Так вот, у меня есть вопрос:

  1. У меня есть 2 файла json, один из которых я создал, добавив в свой проект, а другой — при запуске метода WriteData()? Каковы их пути?
  2. Если мой файл data.json в папке DataSource, как я могу записать в него данные? Я могу читать данные с него, используя uri, например GetSimpleTaskAsync(), но я не знаю, как правильно писать в него. (Я пытался преобразовать объект в строку для записи, но не могу прочитать ее снова, наверное, я написал ее неправильно)

Извините за мой длинный пост и мой плохой английский :) Большое спасибо


person Tung Cao    schedule 05.08.2014    source источник


Ответы (1)


Но я хочу записать данные в тот же файл, поэтому я добавил данные хардкорным способом:

Вы путаете папки ms-appx:/// и ms-appdata:/// (или ApplicationData.Current.LocalFolder )

Папка ms-appx доступна только для чтения. Вы не можете писать на него. (или вы можете отредактировать код своего приложения, не проходя процесс сертификации)

Написанный вами файл должен находиться в папке ms-appdata.

person the_nuts    schedule 05.08.2014
comment
Спасибо @the_nuts за идею, это мои проблемы :D . Я исправил GetSimpleTaskAsync(), но все еще не могу прочитать данные. Произошло исключение ArgumentException, и я пытаюсь с ним справиться. - person Tung Cao; 05.08.2014
comment
Как ты это починил? Путь к файлу: ms-appdata:///local/a.json, но он не существует при первом запуске приложения, вы должны сначала написать его - person the_nuts; 05.08.2014
comment
да, сначала нужно записать в файл, чтобы я мог его прочитать. Я заменил «GetSimpleTaskAsync()» кодом в «ReadData2()», немного исправил это. Теперь мое приложение работает без сбоев :) - person Tung Cao; 05.08.2014