为什么我无法使用protobuf-net从二进制数据中读取VarInt字段

本文关键字:数据 二进制 读取 字段 VarInt protobuf-net 为什么 | 更新日期: 2023-09-27 18:18:10

everyone,

我正在使用protobuf-net库将文本数据序列化-反序列化为二进制文件。我过去有类似的错误,但后来我犯了一个错误,将二进制数据写入文本文件。这次我确定该文件是以二进制模式写入的。当我读取数据时,我收到流结束异常:试图读取超过流的末尾。

我在二进制文件中的每个对象之前都有一个消息头。

message HeaderMessage {
  required double timestamp = 1;
  required string ric_code = 2;
  required int32 count = 3;
  required int32 total_message_size = 4;
}

我在固定位置读取字段时遇到异常total_message_size

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 类总是无法读取total_message_size字段。

在 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

读取第 4 个字段的有效负载时引发异常,值为 8a。 (十进制 138(。

堆栈跟踪如下:

   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 有什么问题?在这种情况下有什么问题?

问候阿洛克

为什么我无法使用protobuf-net从二进制数据中读取VarInt字段

0x8a不是

有效的变量。Varint 编码使用 MSB 作为延续位,这意味着:如果设置了 MSB,则至少还有一个预期的字节(它一直持续到设置 MSB,将剩余的 7 位块组合为小端样式(。因此,0x8a不能单独存在于有效的变量中。0x8a和其他东西当然。您可以在电线规格中看到这一点。请确保您没有意外地切断此单独消息的结尾,或错误地报告长度(因为我收集的每条记录都单独包装了大小前缀(。