public Game[] loadFromFile()
        {
            // 加载文档
            XmlDocument document = new XmlDocument();
            document.Load(fname);

            // 加载根节点
            XmlNode root = document.SelectSingleNode(@"/games");

            // 日期信息
            Game game = null;
            Game[] games = null;
            XmlNode nodeInfo = root.SelectSingleNode(@"info");
            if (nodeInfo != null) {
                string date = nodeInfo.SelectSingleNode(@"date").InnerText;
                string number = nodeInfo.SelectSingleNode(@"number").InnerText;
                game = new Game(date, number);
                games = new Game[int.Parse(number) + 50];
                games[0] = game;
            } else {
                throw new Exception("文件格式错误");
            }

            // 所有游戏开始读入
            XmlNodeList glist = root.SelectNodes(@"game");
            int c = 1;
            foreach (XmlNode gnode in glist) {
                string name = gnode.SelectSingleNode("name").InnerText;
                string path = gnode.SelectSingleNode("path").InnerText;
                string type = gnode.Attributes["type"].Value;
                games[c] = new Game(name, path, (GameType)Enum.Parse(typeof(GameType), type));
                c++;
            }
            return games;
        }
        public bool writeToFile(Game[] games)
        {
            if (games != null && games.Length > 0) {
                XmlTextWriter writer = new XmlTextWriter(fname, Encoding.UTF8);
                writer.Formatting = Formatting.Indented; // 设置缩进
                writer.WriteStartDocument();
                writer.WriteStartElement("games"); // 根节点

                // 信息
                writer.WriteStartElement("info");
                {
                    // 日期
                    writer.WriteStartElement("date");
                    writer.WriteString(games[0].name);
                    writer.WriteEndElement();

                    // 数量
                    writer.WriteStartElement("number");
                    writer.WriteString(games[0].path);
                    writer.WriteEndElement();

                    // 文件格式版本
                    writer.WriteStartElement("version");
                    writer.WriteString("1.0");
                    writer.WriteEndElement();
                }
                writer.WriteEndElement();

                // 写入游戏
                for (int i = 1; i < games.Length; i++) {
                    writer.WriteStartElement("game");

                    // 类别作为属性
                    writer.WriteAttributeString("type", games[i].type.ToString());

                    // 名字
                    writer.WriteStartElement("name");
                    writer.WriteString(games[i].name);
                    writer.WriteEndElement();

                    // 地址
                    writer.WriteStartElement("path");
                    writer.WriteString(games[i].path);
                    writer.WriteEndElement();

                    writer.WriteEndElement();
                }
                // 关闭根节点
                writer.WriteEndElement();

                writer.WriteEndDocument();
                writer.Close();
                return true;
            } else {
                throw new ArgumentNullException("games", "没有输入数组或输入的数组为空");
            }
        }
        public Game[] getGames()
        {
            // 获取页面
            string page = getWikiPage();

            // 按行分割页面
            string[] lines = page.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);

            Game[] games = null;
            int c = 0;
            Regex regTag = new Regex(Tags.TAG_REGEX);
            // 遍历每行,提取信息
            for (int i = 0; i < lines.Length; i++) {
                string line = lines[i];
                /*
                 * 以下代码直接理解可能过于抽象
                 * 请配合wiki页面代码理解
                 */
                // 日期标志
                if (line.Contains(Tags.DATE)) {
                    // 第一个用来记录日期和数量
                    Game game = new Game();
                    i++;
                    // 日期
                    game.name = lines[i];
                    i++;
                    // 数量
                    string number = Regex.Match(lines[i], @"\d+").Value;
                    game.path = number;
                    // 建立数组,由于更新的游戏会重复计数,需要预留空间
                    games = new Game[int.Parse(number) + 50];
                    games[c] = game;
                    c++;
                    continue;
                } else if (regTag.IsMatch(line)) { // 匹配到标签
                    // 确认游戏类型
                    GameType type = GameType.unknown;
                    foreach (string tag in Tags.TAGS) {
                        if (line.Contains(tag)) {
                            type = (GameType)Enum.Parse(typeof(GameType), tag);
                            break;
                        }
                    }

                    // 找到开始标记
                    for (; i < lines.Length; i++) {
                        if (lines[i].Contains(Tags.TAG_START))
                            break;
                    }

                    // 不停读取游戏直到结束
                    Regex regContent = new Regex(Tags.CONTENT_REGEX);
                    for (; i < lines.Length; i++) {
                        line = lines[i];
                        // 匹配成功,该行是一个游戏
                        if (regContent.IsMatch(line)) {
                            string name = getName(line);
                            string link = getLink(line);
                            Game game = new Game(name, link, type);
                            games[c] = game;
                            c++;
                            continue;
                        } else if (line.Contains(Tags.TAG_END)) { // 结束标记,该类型已结束
                            break;
                        }
                    }
                }
            }
            return games;
        }