隔离存储文件的困难

发布于 2024-09-30 15:53:23 字数 3862 浏览 1 评论 0原文

我正在 Silverlight 中构建 Windows Phone 7 应用程序。我在使用 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()一次调用中编写的 JSON。这是我的阅读方法:

    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

我已经运行了几次测试。我很确定只有第一个项目会被读回。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

末蓝 2024-10-07 15:53:23

乍一看,您的流数据似乎没有刷新到磁盘。

您可能认为 using 块在Disposes 流时将执行刷新。然而我发现情况并非总是如此,有时最好在最后强制执行Flush()

我记得最近在我们从 Microsoft 团队收到的移植到 WP7 的代码库中,他们正在强制进行 Flush。我最初对此提出质疑,认为 Dispose 应该处理这个问题,但是由于它正在工作并且我们的截止日期很短,所以我没有进一步调查它。

放手吧,看看会发生什么......:)

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... :)

抠脚大汉 2024-10-07 15:53:23

您是否尝试过显式调用

writer.Close()

而不是依赖 writer.Dispose()

Have you tried explicitly calling

writer.Close()

rather than relying on writer.Dispose()

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文