Protobuf-net: Serializing a 3rd party class with a Stream data member

前端 未结 2 1127
孤独总比滥情好
孤独总比滥情好 2021-01-23 01:54

How do you serialize a Stream (or more correctly Stream derived) data member of a class?

Assuming we have a 3rd Party class that we can\'t attribute:

pub         


        
2条回答
  •  轻奢々
    轻奢々 (楼主)
    2021-01-23 02:28

    Not to make Marc claw his own hands off... but in case anyone else wants to create a surrogate for Stream I've adapted Marc's surrogate example from the answer:

    [ProtoContract]
    public class StreamSurrogate
    {
        [ProtoMember(1)]
        public byte[] Data { get; set; }
    
        public static explicit operator Stream(StreamSurrogate value)
        {
            if (value == null)
            {
                return null;
            }
    
            return new MemoryStream(value.Data);
    }
    
        public static explicit operator StreamSurrogate(Stream value)
        {
            if (value == null)
            {
                return null;
            }
    
            if (value is MemoryStream)
            {
                return new StreamSurrogate { Data = ((MemoryStream)value).ToArray() };
            }
            else
            {
                // Probably a better way to do this...
                StreamSurrogate ss = new StreamSurrogate();
    
                ss.Data = new byte[value.Length];
                value.Read(ss.Data, 0, (int)value.Length);
                return ss;
            }
        }
    }
    

    And then for the RuntimeTypeModel:

    MetaType mt2 = RuntimeTypeModel.Default.Add(typeof(Stream), true);
    
        mt2.AddSubType(1, typeof(MemoryStream));
        mt2.SetSurrogate(typeof(StreamSurrogate));
    

    In which case f2 in my example appears to be fully correct!

    Yes there are a lot of potential troubles with trying to serialize Stream - perhaps it would be wiser for me to set the surrogate on the MemoryStream subtype only since I know my particular case will always be using MemoryStreams for Data. However my line of thinking for registering the surrogate on Stream is as follows:

    1. The data member of the class is a Stream.
    2. Any Stream derived class could have been used on the original object and most of them likely can't be recreated.
    3. However since the data member is a Stream, any Stream derived class should suffice for the deserialized object (since it only must support Stream).
    4. MemoryStream is probably the best candidate in most cases for the deserialized stream.

提交回复
热议问题