简体   繁体   English

XML 反序列化/序列化问题

[英]Problem with XML deserialization/serialization

I am trying to implement save and load mechanic to my game.我正在尝试为我的游戏实现保存和加载机制。 Hovewer for some reason it doesnt want to work.但是由于某种原因它不想工作。 I keep getting the same error message : XmlException: The data at the root level is invalid. Line 1, position 1.我不断收到相同的错误消息: XmlException: The data at the root level is invalid. Line 1, position 1. XmlException: The data at the root level is invalid. Line 1, position 1. . XmlException: The data at the root level is invalid. Line 1, position 1. .. Here's my code to create the serialized xml file:这是我创建序列化 xml 文件的代码:

 public void Save()
    {
        Save newsave = new Save();
        if (Time.timeScale == 0)
        {
            int unit_id = 0;
            GameObject[] units = new GameObject[check_number_of_units()];

            GameObject[] friendlies = GameObject.FindGameObjectsWithTag("Friend");
            GameObject[] enemyosldiers = GameObject.FindGameObjectsWithTag("Enemy");
            GameObject[] allunits = enemyosldiers.Concat(friendlies).ToArray();
            foreach (GameObject g in allunits)
            {
                Debug.Log(unit_id);
                Debug.Log(check_number_of_units());
                units[unit_id] = g;
                unit_id++;
            }
            newsave.cash = id.cash;
            newsave.enemy_cash = id.enemycash;
            newsave.units = units;
            newsave.scenename = SceneManager.GetActiveScene().name;
            FileStream file = File.Create(Application.persistentDataPath + "/gamesave.save");
            DataContractSerializer bf = new DataContractSerializer(newsave.GetType());
            MemoryStream streamer = new MemoryStream();

            bf.WriteObject(streamer, newsave);

            file.Write(streamer.GetBuffer(), 0, streamer.GetBuffer().Length);

            file.Close();
        }
    }

Here's the Save class:这是 Save 类:

[System.Serializable]
[DataContract]
public class Save
{
    [DataMember]
    public int cash;
    [DataMember]
    public int enemy_cash;
    [DataMember]
    public string scenename;
    [DataMember]
    public GameObject[] units;


}

And here's the deserialization code:这是反序列化代码:

public void Load()
    {
        if (File.Exists(Application.persistentDataPath + "/gamesave.save"))
        {
            Save loadedsave = new Save();
            DataContractSerializer bf = new DataContractSerializer(loadedsave.GetType());
            FileStream file = File.Open(Application.persistentDataPath + "/gamesave.save", FileMode.Open);
            loadedsave = (Save)bf.ReadObject(file);
            file.Close();
            scene_has_been_loaded = true;
            units = loadedsave.units;
            cash = loadedsave.cash;
            enemycash = loadedsave.enemy_cash;
            SceneManager.LoadScene(loadedsave.scenename);

        }
    }

I'm lost.我迷路了。 What makes all of this even more confusing is the fact that the error only appears when allunits[] isn't empty更令人困惑的是,错误仅在allunits[]不为空时出现

The problem is with this line:问题出在这一行:

file.Write(streamer.GetBuffer(), 0, streamer.GetBuffer().Length);

You generally don't want to access stream's data via GetBuffer() , because it returns underlying byte array which can be larger than the data you wrote into the stream .您通常不想通过GetBuffer()访问流的数据,因为它返回的底层字节数组可能大于您写入流中的数据

Either use stream.CopyTo method like this:要么像这样使用stream.CopyTo方法:

streamer.Seek(0, SeekOrigin.Begin); // dont forget to seek to the start of the stream
streamer.CopyTo(file);

Or simply write directly to the file, without using MemoryStream at all:或者直接写入文件,根本不使用MemoryStream

FileStream file = File.Create(Application.persistentDataPath + "/gamesave.save");
DataContractSerializer bf = new DataContractSerializer(newsave.GetType());
bf.WriteObject(file , newsave);
file.Close();

You colud try to create a model class for your units, thar store the properties, that are needed to reconstruct the GameObjects.您可以尝试为您的单位创建一个模型类,然后存储重建游戏对象所需的属性。 I would not expect GameObject to be XmlSerializable since the XmlSerializer must know which System.Type to instanciate to fill the array.我不希望 GameObject 是 XmlSerializable,因为 XmlSerializer 必须知道要实例化哪个 System.Type 以填充数组。 GameObject is a abstract class and therefore not instanciable. GameObject 是一个抽象类,因此不是不可实例化的。

[DataContract]
public class Unit
{
    [DataMember]
    public bool IsFriend { get; set; }
    [DataMember]
    public string Name { get; set; }
}

请检查您是否像为 Save 对象那样设置了GameObject 可序列化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM