XML 文档中存在错误(不断将垃圾添加到文件末尾)

本文关键字:添加 文件 存在 文档 错误 XML | 更新日期: 2024-10-26 00:49:56

我正在制作一个游戏,我正在序列化保存游戏数据,数据只是一些布尔值、整数和浮点数的列表。

但是大约 50% 的时间,当数据尝试保存或加载时,我会收到错误,说"XML 文档中有错误"。错误始终位于文件末尾,即使它已更改大小或我添加了其他变量。

XML 数据的最后一部分似乎被复制了两次。XML 的最后一行应为:

</LevelStats>

但是当发生错误时,它通常会读取

</LevelStats>>

</LevelStats>tats>

或者最后一行的其他一小部分重复。

这是我正在序列化的类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using Microsoft.Xna.Framework.Storage;
using System.IO;
namespace Jetpack.Classes
{
    [Serializable]
    public struct LevelStats
    {
        // Player Bests
        public List<float?> fTimeList;
        public List<int?> iScoreList;
        public List<int?> iFuelList;
        // Time
        public List<bool> bBronzeTimeList;
        public List<bool> bSilverTimeList;
        public List<bool> bGoldTimeList;
        // Score
        public List<bool> bBronzeScoreList;
        public List<bool> bSilverScoreList;
        public List<bool> bGoldScoreList;
        // Fuel
        public List<bool> bBronzeFuelList;
        public List<bool> bSilverFuelList;
        public List<bool> bGoldFuelList;
        // Level Complete
        public List<bool> bIsLevelComplete;
    }
}

这是我保存加载数据的方法:

区域保存和负载级别统计

    public static void SaveLevelStats(LevelStats levelStats, string filename)
    {
        // Get the path of the save game
        string fullpath = System.IO.Path.Combine(Directory.GetCurrentDirectory(), filename);
        // Open the file, creating it if necessary
        FileStream stream = File.Open(fullpath, FileMode.OpenOrCreate);
        try
        {
            // Convert the object to XML data and put it in the stream
            XmlSerializer serializer = new XmlSerializer(typeof(LevelStats));
            serializer.Serialize(stream, levelStats);
        }
        finally
        {
            // Close the file
            stream.Close();
        }
    }
    public static LevelStats LoadLevelStats(string filename)
    {
        LevelStats levelStats;
        // Get the path of the save game
        string fullpath = System.IO.Path.Combine((Directory.GetCurrentDirectory()), filename);
        // Open the file
        FileStream stream = File.Open(fullpath, FileMode.OpenOrCreate,
        FileAccess.Read);
        try
        {
            // Read the data from the file
            XmlSerializer serializer = new XmlSerializer(typeof(LevelStats));
            levelStats = (LevelStats)serializer.Deserialize(stream);
        }
        finally
        {
            // Close the file
            stream.Close();
        }
        return (levelStats);
    }
    #endregion

最后是XML文件

<?xml version="1.0"?>
<LevelStats xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <fTimeList>
    <float xsi:nil="true" />
    <float>19.016552</float>
    <float>9.766692</float>
    <float>62.9992142</float>
    <float>11.6666632</float>
    <float xsi:nil="true" />
    <float xsi:nil="true" />
    <float xsi:nil="true" />
    <float xsi:nil="true" />
    <float xsi:nil="true" />
    <float xsi:nil="true" />
  </fTimeList>
  <iScoreList>
    <int xsi:nil="true" />
    <int>690</int>
    <int>390</int>
    <int>690</int>
    <int>200</int>
    <int xsi:nil="true" />
    <int xsi:nil="true" />
    <int xsi:nil="true" />
    <int xsi:nil="true" />
    <int xsi:nil="true" />
    <int xsi:nil="true" />
  </iScoreList>
  <iFuelList>
    <int xsi:nil="true" />
    <int>293</int>
    <int>206</int>
    <int>1134</int>
    <int>202</int>
    <int xsi:nil="true" />
    <int xsi:nil="true" />
    <int xsi:nil="true" />
    <int xsi:nil="true" />
    <int xsi:nil="true" />
    <int xsi:nil="true" />
  </iFuelList>
  <bBronzeTimeList>
    <boolean>false</boolean>
    <boolean>true</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
  </bBronzeTimeList>
  <bSilverTimeList>
    <boolean>false</boolean>
    <boolean>true</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
  </bSilverTimeList>
  <bGoldTimeList>
    <boolean>false</boolean>
    <boolean>true</boolean>
    <boolean>true</boolean>
    <boolean>false</boolean>
    <boolean>true</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
  </bGoldTimeList>
  <bBronzeScoreList>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>true</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
  </bBronzeScoreList>
  <bSilverScoreList>
    <boolean>false</boolean>
    <boolean>true</boolean>
    <boolean>false</boolean>
    <boolean>true</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
  </bSilverScoreList>
  <bGoldScoreList>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
  </bGoldScoreList>
  <bBronzeFuelList>
    <boolean>false</boolean>
    <boolean>true</boolean>
    <boolean>false</boolean>
    <boolean>true</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
  </bBronzeFuelList>
  <bSilverFuelList>
    <boolean>false</boolean>
    <boolean>true</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
  </bSilverFuelList>
  <bGoldFuelList>
    <boolean>false</boolean>
    <boolean>true</boolean>
    <boolean>true</boolean>
    <boolean>false</boolean>
    <boolean>true</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
  </bGoldFuelList>
  <bIsLevelComplete>
    <boolean>false</boolean>
    <boolean>true</boolean>
    <boolean>true</boolean>
    <boolean>true</boolean>
    <boolean>true</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
    <boolean>false</boolean>
  </bIsLevelComplete>
</LevelStats>

您能为我提供的任何帮助将不胜感激。

谢谢。

XML 文档中存在错误(不断将垃圾添加到文件末尾)

由于 SaveLevelStats 是静态的,您是否可能从多个线程调用它?

像序列化程序所做的那样写入文件流不是线程安全的。

最简单的解决方案是在读取和写入文件时使用锁。如果您仍在从多个线程读取和/或写入,请小心。