无法反序列化数据

时间:2015-06-19 02:16:56

标签: c# unity3d protobuf-net rijndaelmanaged

我开始创建一个Unity游戏作为Visual Studio项目。我创建了一个用于测试的辅助项目(WinForms),因为我不知道单元测试。在那里,我的所有代码都完美无缺,即使使用的protobuf-net DLL是Unity的一个,序列化类也能完美运行。现在,当我开始使用Unity时,我复制了我的所有代码和DLL,用于protobuf-net和MySQL.Data。出于某种原因,我无法获得(基本上)相同的代码。反序列化时总是会出现异常,主要是:

  

源数据中的无效字段:0

这个

  

源数据中出现意外的最终组;这通常意味着源数据已损坏

这是最后一个异常的堆栈跟踪:

  

ProtoBuf.ProtoException:源数据中意外的端组;这通常意味着源数据已损坏   在ProtoBuf.ProtoReader.ReadFieldHeader()   at(wrapper dynamic-method)NeohumanSoftware.AoN.UserInformation.User.proto_2(object,ProtoBuf.ProtoReader)   在ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read(object,ProtoBuf.ProtoReader)   在ProtoBuf.Meta.RuntimeTypeModel.Deserialize(int,object,ProtoBuf.ProtoReader)   在ProtoBuf.Meta.TypeModel.DeserializeCore(ProtoBuf.ProtoReader,System.Type,object,bool)   在ProtoBuf.Meta.TypeModel.Deserialize(System.IO.Stream,object,System.Type,ProtoBuf.SerializationContext)   在ProtoBuf.Meta.TypeModel.Deserialize(System.IO.Stream,object,System.Type)   在ProtoBuf.Serializer.Deserialize(System.IO.Stream)< 0x000ae>   在NeohumanSoftware.AoN.Storage.SerializationHandler.DeSerialize(string)< 0x00140>   在NeohumanSoftware.AoN.Storage.DataHandler.DeserializeUser(string)

我省略了堆栈跟踪的最后一部分,因为它不相关。我不明白它为什么在Visual Studio中工作但在Unity中不工作。这是序列化器:

using (MemoryStream ms = new MemoryStream())
{
    Serializer.Serialize(ms, ToSerialize);
    return ms.ToArray();
}

这就是反序列化器:

using (MemoryStream ms = new MemoryStream(ToDeSerialize))
{
    return Serializer.Deserialize<T>(ms);
}

这是序列化的对象,它是&#34; heart&#34;游戏的一切都来自User.user:

[ProtoContract]
internal class User
{
    internal static User user { get; set; }

    [ProtoMember(1)]
    internal Something uSomething { get; private set; }
    [ProtoMember(2)]
    internal bool uSomething2 { get; set; }
    [ProtoMember(3)]
    internal Something3 uSomething3 { get; set; }
    [ProtoMember(4)]
    internal Something4 uSomething4 { get; private set; }
    [ProtoMember(5)]
    internal Something5 uSomething5 { get; private set; }

所有这些自定义类都有[ProtoContract]属性以及至少一个[ProtoMember],除了这些之外我不使用任何其他属性。这是游戏的流程:

  1. 创建数据。
  2. 数据已序列化。
  3. 传递序列化数据以进行加密(RijndaelManaged)。
  4. 加密和序列化数据将写入文件。
  5. 游戏结束
  6. 从文件加载数据。
  7. 使用完全相同的密钥和IV(随机生成并存储)
  8. 对数据进行未加密
  9. 数据已反序列化。
  10. 游戏开始
  11. 编辑: 尝试使用Visual Studio的项目来反序列化Unity的数据 NOT 工作。尝试使用Unity反序列化Visual Studio的数据 NOT 工作。 Unity似乎根本不喜欢protobuf-net ......

    EDIT2: 我将序列化方法改为:

    byte[] b;
    using (MemoryStream ms = new MemoryStream())
    {
        Serializer.Serialize(ms, toXML);
        b = new byte[ms.Position];
        var fullB = ms.GetBuffer();
        Array.Copy(fullB, b, b.Length);
    }
    

    这就是我得到的:

      

    ProtoBuf.ProtoException:无效的线型;这通常意味着您在不截断或设置长度的情况下覆盖了文件;见Using Protobuf-net, I suddenly got an exception about an unknown wire-type   在ProtoBuf.ProtoReader.SkipField()   at(wrapper dynamic-method)NeohumanSoftware.AoN.UserInformation.User.proto_2(object,ProtoBuf.ProtoReader)   在ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read(object,ProtoBuf.ProtoReader)   在ProtoBuf.Meta.RuntimeTypeModel.Deserialize(int,object,ProtoBuf.ProtoReader)   在ProtoBuf.Meta.TypeModel.DeserializeCore(ProtoBuf.ProtoReader,System.Type,object,bool)   在ProtoBuf.Meta.TypeModel.Deserialize(System.IO.Stream,object,System.Type,ProtoBuf.SerializationContext)   在ProtoBuf.Meta.TypeModel.Deserialize(System.IO.Stream,object,System.Type)   在ProtoBuf.Serializer.Deserialize(System.IO.Stream)&lt; 0x000ae&gt;

    如果有帮助,这些是对文件方法的读写:

    internal static void SaveUser(string userSerialized)
    {
        File.WriteAllText(SomePath, userSerialized);
    }
    
    internal static void LoadUser(string userSerialized)
    {
        File.ReadAllText(SomePath);
    }
    

    编辑3: 在Unity的项目中,我在Visual Studio的项目中没有这些:

    internal static Coordinates FromVector3(Vector3 vector)
    {
        return new Coordinates(vector.x, vector.y, vector.z);
    }
    internal static Vector3 ToVector3(Coordinates c)
    {
        return new Vector3(c.X, c.Y, c.Z);
    }
    

    这些在Coordinates类中,它有[ProtoContract]和[ProtoMember]用于X,Y和Z.注释这两种方法会阻止我接收异常,但序列化仍然不起作用(用户属性)都是&#34;新&#34;)

1 个答案:

答案 0 :(得分:0)

<强>解决

放弃对protobuf-net的所有希望后,我切换到DataCotractSerializer,它以某种方式在Unity上运行。我仍然遇到很多问题所以我决定关闭加密并使用Visual Studio读取XML; 该文件完全正常。我的3个事件处理程序仍然存在很多问题(2个用于游戏启动,另外每次创建一个特殊对象),所以我不得不删除事件处理程序并手动执行操作(这很痛苦) a $$)。 毕竟,我设法将Protobuf-net添加回来,一切正常(注意protobuf-net给我一个89字节的文件,DCS'3.5 KB文件)

因此,这个非常奇怪的问题的最终解决方案是:

  1. 禁用功能齐全的RijndaelManaged实施
  2. 禁用所有事件处理程序
  3. 如果有人可以帮助我理解为什么RijdnaelManaged在Visual Studio上工作但不在Unity上工作,请发表评论。