Сложность с IsolatedStorageFile - PullRequest
1 голос
/ 03 ноября 2010

Я создаю приложение для Windows Phone 7 в Silverlight.У меня возникают трудности с использованием IsolatedStorageFile.

Следующий метод должен записать некоторые данные в файл:

    private static void writeToFile(IList<Story> stories)
    {
        IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication();
        using (IsolatedStorageFileStream stream = storage.OpenFile(STORIES_FILE, FileMode.Append))
        {
            using (StreamWriter writer = new StreamWriter(stream))
            {
                StringBuilder toJson = new StringBuilder();

                IList<StoryJson> storyJsons = (from story in stories
                                               where !storageStories.Contains(story)
                                               select story.ToStoryJson()).ToList();

                writer.Write(JsonConvert.SerializeObject(storyJsons));
            }

        }

#if DEBUG
            StreamReader reader = new StreamReader(storage.OpenFile(STORIES_FILE, FileMode.Open));
            string contents = reader.ReadToEnd();
#endif
        }

В конце DEBUG для меня, чтобы проверитьчто данные на самом деле пишутся.Я подтвердил, что это так.Этот метод вызывается 6+ раз.Каждый раз добавляется больше данных.

Однако, когда я иду читать данные, я получаю только тот JSON, который я написал в одном вызове writeToFile().Вот мой метод для чтения:

    private static IList<Story> storageStories;
    private static IList<Story> readFromStorage()
    {
        if (storageStories != null)
        {
            return storageStories;
        }

        IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication();

        if (! storage.FileExists(STORIES_FILE))
        {
            storage.CreateFile(STORIES_FILE);
            storageStories = new List<Story>();
            return storageStories;
        }

        string contents;
        using (IsolatedStorageFileStream stream = storage.OpenFile(STORIES_FILE, FileMode.OpenOrCreate))
        {
            using (StreamReader reader = new StreamReader(stream))
            {
                contents = reader.ReadToEnd();
            }
        }

        JsonSerializer serializer = new JsonSerializer();
        storageStories = JArray.Parse(contents).Select(storyData => storyOfJson(serializer, storyData)).ToList();
        return storageStories;
    }

Что я могу здесь делать не так?Я неправильно пишу в файл?Я почти уверен, что единственные данные, которые могут быть прочитаны, - это данные первой записи.

Обновление : я добавил два Flush() вызова, но они вылетали:

  private static void writeToFile(IList<Story> stories)
        {
            IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication();
            using (IsolatedStorageFileStream stream = storage.OpenFile(STORIES_FILE, FileMode.Append))
            {
                using (StreamWriter writer = new StreamWriter(stream))
                {
                    StringBuilder toJson = new StringBuilder();

                    IList<StoryJson> storyJsons = (from story in stories
                                                   where !storageStories.Contains(story)
                                                   select story.ToStoryJson()).ToList();

                    writer.Write(JsonConvert.SerializeObject(storyJsons));
                    writer.Flush();
                }
                // FAILS
                // "Cannot access a closed file." {System.ObjectDisposedException}

                stream.Flush();
            }
        }

Если я закомментирую stream.Flush(), но оставлю writer.Flush(), у меня возникнет та же проблема.

Обновление 2 : я добавил несколько операторов печати.Похоже, все становится сериализованным:

Serializing for VID 43
Serializing for VID 17
Serializing for VID 6
Serializing for VID 33
Serializing for VID 4
Serializing for VID 5
Serializing for VID 3

Но на самом деле читается только первый набор:

Deserializing stories with vid: 43

Я провел тест еще несколько раз.Я почти уверен, что только первый элемент читается обратно.

Ответы [ 2 ]

0 голосов
/ 26 ноября 2010

Вы пытались явно вызывать

writer.Close()

вместо того, чтобы полагаться на писателя. Dispose ()

0 голосов
/ 04 ноября 2010

На первый взгляд кажется, что данные вашего потока не записываются на диск.

Возможно, вы думаете, что блок using выполнит сброс, когда он Disposes сделает поток.Однако я обнаружил, что это не всегда так, и иногда лучше всего принудительно ввести Flush() в конце.

Я недавно помню, что в кодовой базе, которую мы получили от команды Microsoft для переноса на WP7, они заставляли Flush.Сначала я задал этот вопрос, думая, что Dispose должен справиться с этим, однако, поскольку он работал , и мы были в сжатые сроки, я не стал его расследовать.

Отпусти,посмотрим что получится ...:)

...