【问题标题】:Serialization exception: Attempting to deserialize an empty stream序列化异常:试图反序列化一个空流
【发布时间】:2019-09-21 18:02:48
【问题描述】:

我正在制作一个游戏并将其用作我的保存/加载系统,然后将数据存储在单独的“GameData”脚本中。当我第一次尝试启动游戏时,我收到以下错误:

序列化异常:试图反序列化一个空流。

我尝试检查长度是否大于 0 并尝试了 try/catch 版本。他们都得到了同样的错误,它陷入了一个循环。也许有一种方法可以检查您是否第一次打开游戏并先保存?我宁愿找到一种方法来确保文件在加载之前有数据。或者也许我可以创建一个数据而不是使用null?任何帮助将不胜感激。

这是脚本的长度版本。

using UnityEngine;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System;

public static class SaveSystem
{
    public static void SaveData(PlayerCollision playerCol)
    {
        BinaryFormatter formatter = new BinaryFormatter();
        string path = Application.persistentDataPath + "/player.fun";
        FileStream stream = new FileStream(path, FileMode.Create);

        GameData data = new GameData(playerCol);

        formatter.Serialize(stream, data);
        stream.Close();
    }

    public static GameData LoadData()
    {
        string path = Application.persistentDataPath + "/player.fun";
        if (File.Exists(path) && path.Length > 0)
        {
            BinaryFormatter formatter = new BinaryFormatter();
            FileStream stream = new FileStream(path, FileMode.Open);
            GameData data = formatter.Deserialize(stream) as GameData;
            stream.Close();
            return data;
        }
        else
        {
            Debug.LogError("Save file was not found in " + path);
            return null;

        }
    }
}

这是脚本的 try/catch 版本。

using UnityEngine;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System;

public static class SaveSystem
{
    public static void SaveData(PlayerCollision playerCol)
    {
        BinaryFormatter formatter = new BinaryFormatter();
        string path = Application.persistentDataPath + "/player.fun";
        FileStream stream = new FileStream(path, FileMode.Create);

        GameData data = new GameData(playerCol);

        formatter.Serialize(stream, data);
        stream.Close();
    }

    public static GameData LoadData()
    {
        try
        {
            string path = Application.persistentDataPath + "/player.fun";
            if (File.Exists(path))
            {
                BinaryFormatter formatter = new BinaryFormatter();
                FileStream stream = new FileStream(path, FileMode.Open);
                GameData data = formatter.Deserialize(stream) as GameData;
                stream.Close();
                return data;
            }
            else
            {
                Debug.LogError("Save file was not found in " + path);
                return null;
            }
        }
        catch (System.Exception e)
        {
            Debug.LogError("Error Loading Save " + e);
            return null;
        }
    }
}

【问题讨论】:

  • path.Length 不是你想要的。改为检查stream.Length。您的文件似乎有 0 个字节。
  • 感谢您的帮助!它摆脱了错误。然后它开始运行 debug.log 错误消息的循环,但我设法通过在“else{}”下运行保存函数而不是仅使用“return null”来解决这个问题。谢谢!!

标签: c# unity3d exception serialization binaryformatter


【解决方案1】:

我只是发布最终解决方案,因为太多人修复了错误,并且不会分享和发布以帮助将来的任何人。 正如上面的“Dymaniod”指出的那样,我想使用“stream.length”而不是“path.length”,因为“WarmedxMints”也指出了统一的答案,路径的长度总是大于 0。 我仍然有一个加载错误循环。工作的最终脚本如下。 感谢帮助过的两位!!

using UnityEngine;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System;

public static class SaveSystem
{



    public static void SaveData(PlayerCollision playerCol)
    {
        BinaryFormatter formatter = new BinaryFormatter();
        string path = Application.persistentDataPath + "/player.fun";
        FileStream stream = new FileStream(path, FileMode.Create);

        GameData data = new GameData(playerCol);

        formatter.Serialize(stream, data);
        stream.Close();
    }

    public static GameData LoadData(PlayerCollision playerCol)
    {
        string path = Application.persistentDataPath + "/player.fun";
        FileStream stream = new FileStream(path, FileMode.Open);
        if (File.Exists(path) && stream.Length > 0)
        {
            BinaryFormatter formatter = new BinaryFormatter();
            GameData data = formatter.Deserialize(stream) as GameData;
            stream.Close();
            return data;
        }
        else
        {
            Debug.LogError("Save file was not found in " + path);
            BinaryFormatter formatter = new BinaryFormatter();
            GameData data = new GameData(playerCol);
            formatter.Serialize(stream, data);
            stream.Close();
            return data;
        }
    }

}

【讨论】:

  • 因为FileStreamIDisposable 你应该使用using(FileStream stream = new FileStream(path, FileMode.Create) { ... } 然后你不必隐式调用stream.Close
  • 我也不会使用new FileStream,而是使用File.Open(path, fileMode, fileAccess, fileShare),例如using (var stream = File.Open(path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
猜你喜欢
  • 1970-01-01
  • 2011-08-28
  • 1970-01-01
  • 2023-03-23
  • 2020-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多