C# 为什么我不能使用protobuf网络从二进制数据中读取变量字段
各位, 我使用protobuf网络库将反序列化文本数据序列化为二进制文件。我过去也有类似的错误,但后来我犯了一个错误,将二进制数据写入文本文件。这次我确信文件是以二进制模式编写的。当我读取数据时,我得到EndOfStream异常:试图读取流的末尾。 我在二进制文件中的每个对象之前都有一个消息头C# 为什么我不能使用protobuf网络从二进制数据中读取变量字段,c#,serialization,protobuf-net,C#,Serialization,Protobuf Net,各位, 我使用protobuf网络库将反序列化文本数据序列化为二进制文件。我过去也有类似的错误,但后来我犯了一个错误,将二进制数据写入文本文件。这次我确信文件是以二进制模式编写的。当我读取数据时,我得到EndOfStream异常:试图读取流的末尾。 我在二进制文件中的每个对象之前都有一个消息头 message HeaderMessage { required double timestamp = 1; required string ric_code = 2; required in
message HeaderMessage {
required double timestamp = 1;
required string ric_code = 2;
required int32 count = 3;
required int32 total_message_size = 4;
}
当我在固定位置读取总消息大小字段时,出现异常
HEADER: 1111 1 1 hk 0
File: 398909440 bytes
Reading data objects:
1073561: 09 e3 a5 9b c4 0c b3 e0 40 12 07 31 30 39 33 2e 48 4b 18 04 20 5a
1073677: 09 e3 a5 9b c4 0c b3 e0 40 12 07 30 32 39 37 2e 48 4b 18 02 20 2d
1073748: 09 e3 a5 9b c4 0c b3 e0 40 12 07 30 32 39 37 2e 48 4b 18 04 20 5a
1073864: 09 e3 a5 9b c4 0c b3 e0 40 12 07 38 31 37 33 2e 48 4b 18 02 20 2d
1073935: 09 e3 a5 9b c4 0c b3 e0 40 12 07 38 31 37 33 2e 48 4b 18 04 20 5b
1074052: 09 e3 a5 9b c4 0c b3 e0 40 12 07 30 32 33 35 2e 48 4b 18 02 20 2d
1074123: 09 e3 a5 9b c4 0c b3 e0 40 12 07 30 36 30 33 2e 48 4b 18 02 20 2d
1074194: 09 e3 a5 9b c4 0c b3 e0 40 12 07 30 36 30 33 2e 48 4b 18 04 20 5b
1074311: 09 e3 a5 9b c4 0c b3 e0 40 12 07 30 32 33 35 2e 48 4b 18 06 20 8a
在上述输出中,第一个字段是流位置。河流总长度为398909440。因此,这条河不可能已经到了尽头。我试图在无法读取时打印单个字段,我发现ProtoReader类总是无法读取总消息大小字段
在aboe输出中,最后一行是protobuf net无法读取数据的罪魁祸首
1074311: 09 e3 a5 9b c4 0c b3 e0 40 12 07 30 32 33 35 2e 48 4b 18 06 20 8a
如果拆分字段,数据如下所示:
field1 timestamp field: type: 09 payload: e3 a5 9b c4 0c b3 e0 40
field2 ric_code field: type: 12 payload: 07 30 32 33 35 2e 48 4b
field3 count field: type: 18 payload: 06
field4 total_message_size: type: 20 payload: 8a
at ProtoBuf.ProtoReader.TryReadUInt32VariantWithoutMoving(Boolean trimNegative, UInt32& value) in C:\Dev\protobuf-net\protobuf-net\ProtoReader.cs:line 101
at ProtoBuf.ProtoReader.ReadUInt32Variant(Boolean trimNegative) in C:\Dev\protobuf-net\protobuf-net\ProtoReader.cs:line 138
at ProtoBuf.ProtoReader.ReadInt32() in C:\Dev\protobuf-net\protobuf-net\ProtoReader.cs:line 264
at protobuf_test.Program.Main(String[] args) in H:\Personal\Visual Studio 2010\Projects\protobuf-test\protobuf-test\Program.cs:line 80
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
读取第4个字段的有效负载时引发异常,值为8a。(十进制138)
堆栈跟踪如下所示:
field1 timestamp field: type: 09 payload: e3 a5 9b c4 0c b3 e0 40
field2 ric_code field: type: 12 payload: 07 30 32 33 35 2e 48 4b
field3 count field: type: 18 payload: 06
field4 total_message_size: type: 20 payload: 8a
at ProtoBuf.ProtoReader.TryReadUInt32VariantWithoutMoving(Boolean trimNegative, UInt32& value) in C:\Dev\protobuf-net\protobuf-net\ProtoReader.cs:line 101
at ProtoBuf.ProtoReader.ReadUInt32Variant(Boolean trimNegative) in C:\Dev\protobuf-net\protobuf-net\ProtoReader.cs:line 138
at ProtoBuf.ProtoReader.ReadInt32() in C:\Dev\protobuf-net\protobuf-net\ProtoReader.cs:line 264
at protobuf_test.Program.Main(String[] args) in H:\Personal\Visual Studio 2010\Projects\protobuf-test\protobuf-test\Program.cs:line 80
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
读取值138时有什么问题?在这种情况下,问题是什么
问候,,
Alok0x8a不是有效变量。Varint编码将MSB用作延续位,这意味着:如果设置了MSB,则至少还需要一个字节(它将继续,直到MSB未设置,并将剩余的7位块组合为小尾端样式)。因此,0x8a不能在有效变量中独立存在。0x8a和其他东西,当然。你可以在地图上看到这一点。请确保您没有意外地切断这个单独的消息的结尾,或者错误地报告长度(因为我收集每个记录都是用一个大小前缀来包装的)。谢谢您提供了足够的信息来给出一个考虑的答案,但是这似乎是作者(IIrc是C++)的一个问题,而不是读者(protobuf net)感谢Marc。我在写标题长度时报告了错误的标题长度。基本上,我将头长度放入二进制数据中,然后在编写实际的头消息之前,我更新了其中一个头值,这一定改变了头长度。