开发者

Difficulty with IsolatedStorageFile

I'm building a Windows Phone 7 app in Silverlight. I'm having difficulty using IsolatedStorageFile.

The following method is supposed to write some data to a file:

    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
        }

The DEBUG at the end is for me to check that the data is actually being written. I have verified that it is. This method is called 6+ times. Each time, more data is appended.

However, when I go to read the data, the only JSON I get back is that which I wrote in one call of writeToFile(). Here is my method to read:

    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;
    }

What could I be doing wrong here? Am I writing to the file incorrectly? I'm pretty sure that the only data that is able to be read back is from the first write.

Update: I added two Flush() calls, but it crashes:

  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();
            }
        }

If I comment out the stream.Flush() but leave writer.Flush(), I have the same problem.

Update 2: I added some print statements. Looks like everything is getting serialized:

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

But only the first set is actually being read back:

Deserializing stories with vid: 43

I have run the test a few more times. I'm pretty sure that only the first item is ever being read back.


At first glance it sounds like your stream data is not being flushed to disk.

You are probably thinking that the using block will perform a flush when it Disposes the stream. However I have found that is not always the case and sometimes it is best to force a Flush() at the end.

I remember recently in a codebase that we received from a Microsoft team to port to WP7 that they were forcing a Flush. I questioned it initially, thinking that the Dispose should handle that, however as it was working and we were on a short deadline I did not investigate it further.

Give it go, see what happens... :)


Have you tried explicitly calling

writer.Close()

rather than relying on writer.Dispose()

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜