【问题标题】:XML Serialization of List growing too large列表的 XML 序列化变得太大
【发布时间】:2010-11-12 22:24:19
【问题描述】:

我有一个 C# Windows 窗体应用程序,它在 IRC 频道上运行琐事游戏,并保留它提出的问题,以及我序列化为 XML 以在会话之间保存的类中的排行榜(分数)。我遇到的问题最好用流程来描述,所以这里是:

用户 X 在排行榜类中获得 1 分的条目。类被保存到 XML,XML 包含用户 X 的一个条目。

用户 Y 在排行榜类中获得 1 分的条目。类被保存到 XML,XML 包含用户 X 的重复条目,以及用户 Y 的一个条目。

在不到 20 个用户的情况下运行了一周后,我希望能够用 PHP 编写一个 Web 后端来帮助我使用分数。 XML 文件为 2 兆字节。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization;

namespace IRCTriviaBot
{
    [Serializable()]    
    public class LeaderBoard 
    {
        [Serializable()]
        public class Pair
        {
            public string user;
            public int score;
            public Pair(string usr, int scr)
            {
                user = usr;
                score = scr;
            }
            public Pair() { }
        }
        private static List<Pair> pairs = null;
        public List<Pair> Pairs
        {
            get
            {
                if (pairs==null)
                {
                    pairs = new List<Pair>();

                }
                return pairs;
            }
        }
        public LeaderBoard()
        {

        }
        public void newScore(string usr)
        {
            bool found = false;
            for (int i = 0; i < Pairs.Count && !found; ++i)
            {
                if (Pairs[i].user==usr)
                {
                    found = true; 
                    Pairs[i].score++;
                }
            }
            if (!found)
            {
                Pairs.Add(new Pair(usr, 1));
            }
        }

        public int getScore(string usr)
        {
            bool found = false;
            for (int i = 0; i < Pairs.Count && !found; ++i)
            {
                if (Pairs[i].user == usr)
                {
                    return Pairs[i].score;
                }
            }
            if (!found)
            {
                return 0;
            }
            return 0;
        }
    }
}

这里是序列化和反序列化发生的地方。

       void parseMessage(string message, string user = "")
    {
        if (message == "-startgame-")
        {
            if (!gameStarted)
            {
                gameStarted = true;
                openScores();
                startGame();
            }
        }
        else if (message == "-hint-")
        {
            if (!hintGiven && gameStarted)
            {
                sendMessage("Here's a better hint: " + Form2.qa.Answers[curQ].Trim());
                hintGiven = true;
            }

        }
        else if (message == "-myscore-")
        {
            sendMessage(user + ", your score is: " + leaderB.getScore(user));
        }

        else if (message.ToLower() == Form2.qa.Answers[curQ].ToLower())
        {
            if (gameStarted)
            {
                sendMessage(user + " got it right! Virtual pat on the back!");
                leaderB.newScore(user);
                saveScores();
                System.Threading.Thread.Sleep(2000);
                startGame();
            }
        }
        else if (message == "-quit-")
        {
            if (gameStarted)
            {
                sendMessage("Sorry to see you go! Have fun without me :'(");
                gameStarted = false;
            }
            else
            {
                sendMessage("A game is not running.");
            }
        }
        else
        {
            if (gameStarted)
            {
                //sendMessage("Wrong.");
            }
        }
    }

    void saveScores()
    {
        //Opens a file and serializes the object into it in binary format.
        Stream stream = System.IO.File.Open("scores.xml", FileMode.Open);
        XmlSerializer xmlserializer = new XmlSerializer(typeof(LeaderBoard));

        //BinaryFormatter formatter = new BinaryFormatter();

        xmlserializer.Serialize(stream, leaderB);
        stream.Close();
    }

    void openScores()
    {
        Stream stream = System.IO.File.OpenRead("scores.xml");
        XmlSerializer xmlserializer = new XmlSerializer(typeof(LeaderBoard));

        //BinaryFormatter formatter = new BinaryFormatter();

        leaderB = (LeaderBoard)xmlserializer.Deserialize(stream);
        stream.Close();
    }

【问题讨论】:

  • @Jeremy:我将代码从 pastebin 移到了这里。我看不出这个页面比 pastebin 差多少。
  • 我无法让标记工作。
  • 我可以推荐一个小型数据库吗?
  • 为什么不将数据存储在数据库中而不是 XML 文件中?
  • 为什么写用户 Y 会复制用户 X 的数据?

标签: c# xml serialization xml-serialization


【解决方案1】:

我认为这与 pairs 被标记为 static 有关。我不相信XmlSerializer 会在添加元素之前清除列表,因此每次调用openScores() 时,您都会创建重复条目而不是覆盖现有条目。

总的来说,我观察到序列化和全局变量不能很好地配合使用。为此,“全局变量”包括私有静态变量、单例、monostate 这样的类以及线程局部变量。

看起来在使用 XML 和二进制序列化之间也存在一些问题。他们是完全不同的野兽。 XML 序列化只查看类的公共属性,而二进制序列化只查看类的实例字段。此外,XML 序列化会忽略 Serializable 属性。

【讨论】:

  • 作为序列化的新手,二进制区域仅作为 MSDN 文章中的一个工件存在:P
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-13
  • 1970-01-01
  • 1970-01-01
  • 2018-07-18
相关资源
最近更新 更多