0

I am trying to serialize a custom class into a byte[] array using BinaryFormatter, upload it to steam using the steam-api, download it again later and deserialize it back into the custom class. The steam part is already working but when I deserialize the byte[] 90% of the time I receive a SerializationException "end of stream encountered before parsing was completed" or it actually creates the instance of the class but the values are all wrong.

10% of the time is works fine though, not sure why it works sometimes but not most of the time.

The class in question

[Serializable]
public class ReplayEntry
{
    public List<SerializableVector3> Position;
    public List<SerializableVector3> Rotation;
    public List<SerializableVector3> Velocity;
    public float Offset;
    public UGCHandle_t handle;

    \\... Constructors below
}

Serialization:

public static byte[] ObjectToByteArray(Object obj)
{
    BinaryFormatter bf = new BinaryFormatter();
    using (MemoryStream ms = new MemoryStream())
    {
        bf.Serialize(ms, obj);
        ms.Flush();
        return ms.ToArray();  
    }
}

Deserialization:

public static Object ByteArrayToObject(byte[] arrBytes)
{
    using (MemoryStream memStream = new MemoryStream(arrBytes))
    {
        BinaryFormatter binForm = new BinaryFormatter();
        memStream.Write(arrBytes, 0, arrBytes.Length);
        memStream.Seek(0, SeekOrigin.Begin);
        var obj = binForm.Deserialize(memStream);
        return obj;
    }
}

The 'SerializeableVector3' type is because Unity's vector3 is not serializeable

[Serializable]
public struct SerializableVector3
{
    public float x;
    public float y;
    public float z;

    public SerializableVector3(float rX, float rY, float rZ)
    {
        x = rX;
        y = rY;
        z = rZ;
    }

    public static implicit operator Vector3(SerializableVector3 rValue)
    {
        return new Vector3(rValue.x, rValue.y, rValue.z);
    }

    public static implicit operator SerializableVector3(Vector3 rValue)
    {
        return new SerializableVector3(rValue.x, rValue.y, rValue.z);
    }
}
  • 1
    I suspect it's probably not related, but there's no need to call `memStream.Write(arrBytes, 0, arrBytes.Length);` and `memStream.Seek(0, SeekOrigin.Begin);`, since you already passed `arrBytes` to the `MemoryStream` construtor – canton7 Feb 10 '19 at 14:29
  • 1
    `SerializableVector` does not have a parameterless constructor. I think it needs to have one for deserialization to work – canton7 Feb 10 '19 at 14:31
  • See: [Why XML-Serializable class need a parameterless constructor](https://stackoverflow.com/questions/267724/why-xml-serializable-class-need-a-parameterless-constructor). According to Marc Gravell's answer, no default constructor is required for `BinaryFormatter` but one is required for `XmlSerializer`. – Olivier Jacot-Descombes Feb 10 '19 at 14:49
  • @canton7 Thanks I've removed the 2 lines. also SerializableVector is a struct so it can't have a parameterless constructor. I changed it to a class but unfortunately its still not working... – StefanKroell Feb 10 '19 at 15:16
  • Aha I missed that it was a struct. Ignore that comment then. Try and work out the difference between the cases where it does work, and the cases where it doesn't – canton7 Feb 10 '19 at 17:02
  • Are you definitely only passing in SerializableVector at all times when you serialize? Try to serialize then immediately deserialize the same thing just to make sure the problem is in this section of the code and not in the caller. I mean really just serialize the object and pass the resulting byte array straight back to deserialize. – Reasurria Feb 11 '19 at 11:42

0 Answers0