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>
您能为我提供的任何帮助将不胜感激。
谢谢。
由于 SaveLevelStats 是静态的,您是否可能从多个线程调用它?
像序列化程序所做的那样写入文件流不是线程安全的。
最简单的解决方案是在读取和写入文件时使用锁。如果您仍在从多个线程读取和/或写入,请小心。