草庐IT

c# - Protobuf-net:试图读取流的末尾

coder 2023-07-10 原文

我们的系统在使用 protobuf-net 序列化一条消息时,有时但不是每次都会引发下面暴露的错误。错误的原因是什么?我该如何缓解?

请注意,我们已经在使用 DeserializeWithLengthPrefix

更新: 相关代码在这里

private const PrefixStyle PrefixStyleInPlace = PrefixStyle.Fixed32;
public static byte[] SerializeObjectToByteArray<TSerializable>(TSerializable source) where TSerializable : class
    {
        byte[] result;
        using (var memoryStream = SerializeObjectToStream(source))
        {
            result = memoryStream.ToArray();
        }
        return result;
    }


    public static TResult DeserializeObject<TResult>(byte[] source)
    {
        TResult result;
        using (var memoryStream = new MemoryStream(source))
        {
            memoryStream.Position = 0;
            result = Serializer.DeserializeWithLengthPrefix<TResult>(memoryStream,PrefixStyleInPlace);
        }

        return result;
    }

    public static MemoryStream SerializeObjectToStream<TSerializable>(TSerializable source) where TSerializable : class
    {
        var memoryStream = new MemoryStream();

        Serializer.SerializeWithLengthPrefix(memoryStream, source,PrefixStyleInPlace);
        memoryStream.Position = 0;
        return memoryStream;
    }


    public static TResult DeserializeObject<TResult>(MemoryStream sourceStream)
    {
        TResult result;
        result = DeserializeObject<TResult>(sourceStream.ToArray());
        return result;
    }

留言:

System.IO.EndOfStreamException : Attempted to read past the end of the
 stream.
 +++++++++++++++++++ STACK TRACE: at ProtoBuf.ProtoReader.Ensure(Int32 count, Boolean trict) in
 c:\Dev\protobuf-net\protobuf-net\ProtoReader.cs:line 234 at
 ProtoBuf.ProtoReader.ReadString() in
 c:\Dev\protobuf-net\protobuf-net\ProtoReader.cs:line 471 at
 proto_15(Object , ProtoReader ) at
 ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read(Object
 value, ProtoReader source) in
 c:\Dev\protobuf-net\protobuf-net\Serializers\CompiledSerializer.cs:line
 49 at ProtoBuf.Meta.RuntimeTypeModel.Deserialize(Int32 key, Object
 value, ProtoReader source) in
 c:\Dev\protobuf-net\protobuf-net\Meta\RuntimeTypeModel.cs:line 721 at
 ProtoBuf.ProtoReader.ReadTypedObject(Object value, Int32 key,
 ProtoReader reader, Type type) in
 c:\Dev\protobuf-net\protobuf-net\ProtoReader.cs:line 556 at
 proto_16(Object , ProtoReader ) at
 ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read(Object
 value, ProtoReader source) in
 c:\Dev\protobuf-net\protobuf-net\Serializers\CompiledSerializer.cs:line
 49 at ProtoBuf.Meta.RuntimeTypeModel.Deserialize(Int32 key, Object
 value, ProtoReader source) in
 c:\Dev\protobuf-net\protobuf-net\Meta\RuntimeTypeModel.cs:line 721 at
 ProtoBuf.ProtoReader.ReadTypedObject(Object value, Int32 key,
 ProtoReader reader, Type type) in
 c:\Dev\protobuf-net\protobuf-net\ProtoReader.cs:line 556 at
 proto_11(Object , ProtoReader ) at
 ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read(Object
 value, ProtoReader source) in
 c:\Dev\protobuf-net\protobuf-net\Serializers\CompiledSerializer.cs:line
 49 at ProtoBuf.Meta.RuntimeTypeModel.Deserialize(Int32 key, Object
 value, ProtoReader source) in
 c:\Dev\protobuf-net\protobuf-net\Meta\RuntimeTypeModel.cs:line 721 at
 ProtoBuf.ProtoReader.ReadTypedObject(Object value, Int32 key,
 ProtoReader reader, Type type) in
 c:\Dev\protobuf-net\protobuf-net\ProtoReader.cs:line 556 at
 proto_16(Object , ProtoReader ) at
 ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read(Object
 value, ProtoReader source) in
 c:\Dev\protobuf-net\protobuf-net\Serializers\CompiledSerializer.cs:line
 49 at ProtoBuf.Meta.RuntimeTypeModel.Deserialize(Int32 key, Object
 value, ProtoReader source) in
 c:\Dev\protobuf-net\protobuf-net\Meta\RuntimeTypeModel.cs:line 721 at
 ProtoBuf.ProtoReader.ReadTypedObject(Object value, Int32 key,
 ProtoReader reader, Type type) in
 c:\Dev\protobuf-net\protobuf-net\ProtoReader.cs:line 556 at
 proto_13(Object , ProtoReader ) at
ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read(Object
 value, ProtoReader source) in
 c:\Dev\protobuf-net\protobuf-net\Serializers\CompiledSerializer.cs:line
 49 at ProtoBuf.Meta.RuntimeTypeModel.Deserialize(Int32 key, Object
 value, ProtoReader source) in
 c:\Dev\protobuf-net\protobuf-net\Meta\RuntimeTypeModel.cs:line 721 at
 ProtoBuf.ProtoReader.ReadTypedObject(Object value, Int32 key,
 ProtoReader reader, Type type) in
 c:\Dev\protobuf-net\protobuf-net\ProtoReader.cs:line 556 at
 proto_16(Object , ProtoReader ) at
 ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read(Object
 value, ProtoReader source) in
 c:\Dev\protobuf-net\protobuf-net\Serializers\CompiledSerializer.cs:line
 49 at ProtoBuf.Meta.RuntimeTypeModel.Deserialize(Int32 key, Object
 value, ProtoReader source) in
 c:\Dev\protobuf-net\protobuf-net\Meta\RuntimeTypeModel.cs:line 721 at
 ProtoBuf.ProtoReader.ReadTypedObject(Object value, Int32 key,
 ProtoReader reader, Type type) in
 c:\Dev\protobuf-net\protobuf-net\ProtoReader.cs:line 556 at
 proto_2(Object , ProtoReader ) at
 ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read(Object
 value, ProtoReader source) in
 c:\Dev\protobuf-net\protobuf-net\Serializers\CompiledSerializer.cs:line
 49 at ProtoBuf.Meta.RuntimeTypeModel.Deserialize(Int32 key, Object
 value, ProtoReader source) in
 c:\Dev\protobuf-net\protobuf-net\Meta\RuntimeTypeModel.cs:line 721 at
 ProtoBuf.Meta.TypeModel.DeserializeWithLengthPrefix(Stream source,
 Object value, Type type, PrefixStyle style, Int32 expectedField,
 TypeResolver resolver, Int32& bytesRead, Boolean& haveObject,
 SerializationContext context) in
 c:\Dev\protobuf-net\protobuf-net\Meta\TypeModel.cs:line 351 at
 ProtoBuf.Serializer.DeserializeWithLengthPrefix[T](Stream source,
 PrefixStyle style, Int32 fieldNumber) in
 c:\Dev\protobuf-net\protobuf-net\Serializer.cs:line 303 at
 ProtoBuf.Serializer.DeserializeWithLengthPrefix[T](Stream source,
 PrefixStyle style) in
 c:\Dev\protobuf-net\protobuf-net\Serializer.cs:line 288 at
 ermeX.Common.ObjectSerializer.DeserializeObject[TResult](Byte[]
 source) in
    [ProtoContract(SkipConstructor = true)]
    [ProtoInclude(100, typeof(BusMessage))]
    [ProtoInclude(200, typeof(TransportMessage))]
    [ProtoInclude(300, typeof(BizMessage))]

代码在这里

 internal abstract class SystemMessage : ISystemMessage, IEquatable<SystemMessage>
    {
        protected SystemMessage():this(Guid.NewGuid(),DateTime.UtcNow)
        {
        }
        protected SystemMessage(Guid messageId,DateTime createdTimeUtc)
        {
            MessageId = messageId;
            CreatedTimeUtc = new DateTime(createdTimeUtc.Ticks);//TODO: UNTIL PROTOBUF-NET FIXES ISSUE 335 
        }

        [ProtoMember(1)]
        public Guid MessageId{get;private set;}

        [ProtoMember(2)]
        public DateTime CreatedTimeUtc { get; private set; }

        ...
    }


    [ProtoContract(SkipConstructor = true)]
    internal sealed class TransportMessage : SystemMessage, ISystemMessage<BusMessage>
    {
        //just for the serializer, remove in the future
        private TransportMessage()
        {
        }

        public TransportMessage(Guid recipient, BusMessage data)
            : this(data.MessageId, data.CreatedTimeUtc, recipient, data)
        {
        }

        public TransportMessage(Guid messageId, DateTime createdTimeUtc, Guid recipient, BusMessage data)
            : base(messageId, createdTimeUtc)
        {
            if (data == null) throw new ArgumentNullException("data");
            if (recipient.IsEmpty()) throw new ArgumentException("recipient cannot be an empty value");
            Recipient = recipient;
            Data = data;
        }

        [ProtoMember(1)]
        public Guid Recipient { get; private set; }

        [ProtoMember(2)]
        public BusMessage Data { get; private set; }
    }
    [ProtoContract(SkipConstructor = true)]
    internal sealed class BusMessage: SystemMessage, ISystemMessage<BizMessage>,IEquatable<BusMessage>
    {
        private BusMessage()
        {

        }
        public BusMessage(Guid publisher,BizMessage data)
            : this(data.MessageId,data.CreatedTimeUtc,publisher, data)
        {


        }

        public BusMessage(Guid messageId, DateTime createdTimeUtc, Guid publisher, BizMessage data) : base(messageId,createdTimeUtc)
        {
            if (data == null) throw new ArgumentNullException("data");
            Publisher = publisher;
            Data = data;
        }
        [ProtoMember(1)]
        public Guid Publisher { get; protected set; }

        [ProtoMember(2)]
        public BizMessage Data { get; protected set; }
    }

    [ProtoContract(SkipConstructor = true)]
    internal sealed class BizMessage : SystemMessage, IEquatable<BizMessage>
    {
        private string _jsonMessage;
        private object _data = null;

        public BizMessage(object data) : base()
        {
            if (data == null) throw new ArgumentNullException("data");
            _data = data;
        }

        private BizMessage(){}

        public static BizMessage FromJson(string jsonData)
        {
            if(string.IsNullOrEmpty(jsonData)) 
                throw new ArgumentException();
            return new BizMessage(){JsonMessage = jsonData};
        }

        [ProtoMember(75)]
        internal string JsonMessage
        {
            get
            {
                if(string.IsNullOrEmpty(_jsonMessage))
                {
                    if (_data == null)
                        throw new ApplicationException(
                            "One of both, _data or the serialized json message must have a value");
                    _jsonMessage = JsonSerializer.SerializeObjectToJson(_data);
                }
                return _jsonMessage;
            }
            private set { _jsonMessage = value; }
        }

        public Type MessageType
        {
            get
            {
                UpdateData();
                if (_data == null)
                    return typeof(void);
                return _data.GetType();
            }
        }

        public object RawData
        {
            get
            {
                UpdateData();
                return _data;
            }
        }

        private void UpdateData()
        {
            if (_data == null)
            {
                if (string.IsNullOrEmpty(_jsonMessage))
                    throw new ApplicationException(
                        "One of both, _data or the serialized json message must have a value");
                _data = JsonSerializer.DeserializeObjectFromJson<object>(_jsonMessage);
            }
        }
    }

最佳答案

当我指定要反序列化的“类型”与序列化的原始类型不同时,我看到了这个错误。我想如果您的对象已更改并且您正在尝试反序列化与新版本不兼容的旧版本对象(即旧字节数组),也可能会发生这种情况。

关于c# - Protobuf-net:试图读取流的末尾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14323279/

有关c# - Protobuf-net:试图读取流的末尾的更多相关文章

  1. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  2. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  3. ruby - 如何模拟 Net::HTTP::Post? - 2

    是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou

  4. Ruby 写入和读取对象到文件 - 2

    好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信

  5. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  6. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  7. ruby - Net::HTTP 获取源代码和状态 - 2

    我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur

  8. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  9. python - 如何读取 MIDI 文件、更改其乐器并将其写回? - 2

    我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的

  10. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

随机推荐