当前位置: 首页 > 知识库问答 >
问题:

从字节数组识别ProtoBuf类

钮兴安
2023-03-14

我正在编写一个程序,处理两个原型消息,我需要处理从不同来源发送的字节[],这些来源发送foo消息或bar消息。由于我无法弄清楚它属于哪个消息,我使用任何类(附带的协议)来解析字节数组并找到它属于哪个类,但遇到了编译时错误。如果我将来添加更多的原型消息类,我可以使用其他方法来检测吗?

//Foo.proto

syntax = "proto3";

option java_outer_classname = "FooProto";

message Foo {
    int32 a = 1;
}

第二个原型

//Bar.proto
syntax = "proto3";

option java_outer_classname = "BarProto";

message Bar {
    int32 b = 1;
}

代码:

Any anyEvent = Any.parseFrom(protoBytes);
if (any.is(Foo.class)
{
  Foo foo = any.unpack(Foo.class);
  ...
} else {
  Bar bar = any.unpack(Bar.class);
  ...
}

尝试调用any时if语句出错。is():

方法是(类

共有1个答案

那弘
2023-03-14

<代码>任何不表示“任何”;它的意思是“通过Any序列化的类型”。如果未将其与任何一起存储:则无法通过任何对其进行解码。

这里的关键点是probuf在消息负载中不包含类型元数据。如果您有BLOB,您通常不知道消息类型是什么。任何通过在包装消息中编码消息类型来解决这个问题,但这里没有。

如果您的设计要有一个API,它可以接受两种不同的非代码消息类型,而事先不知道它是哪种类型:那么您的设计可能很糟糕。因为这对protobuf不起作用。在电线上,a=42的Foo和b=42的条形图之间几乎没有区别;有效载荷相同:

Foowitha=42是字节08 2ABar(代码>条形图),其中b=42是字节08 2A。08表示“字段1,编码为变量”,2A是原始值为42的变量。

更好的设计可能是特定于您的场景的包装消息:

message RootMessage {
  oneof test_oneof {
     Foo foo = 1;
     Bar bar = 2;
  }
}

这添加了一个包装层,类似于任何代码的工作方式,但效率要高得多-它只知道如何将已知类型区分为整数,而不必处理每种可能的类型(作为根类型名)。

 类似资料:
  • 我在Java写一个刽子手程序,但我的问题是,在游戏中,我想显示猜测字母的剩余字母,因为我已经创建了一个字符串alpha,其中包含字母表,我把它一个数组列表,这样我就可以选择玩家猜测的字母。但是我被困在这一点上,我想得到的输出如下:我还附上了我为函数编写的代码。 你还有6个猜测。可用字母:abcdefghijklmnopqrstuvwxyz请猜一个字母:a 你还有6个猜测。可用信函:bcdefghi

  • 我正在编写一个Android应用程序来从图片中提取数独谜题。对于9x9数独网格中的每个单元格,我需要确定它是包含数字1到9中的一个还是空白。我从这样的数独开始: 我使用OpenCV对数独进行预处理,以提取单个数字的黑白图像,然后将它们通过Tesseract。不过,Tesseract有几个限制: Tesseract很大,包含许多我不需要的功能(即全文识别),并且需要英语训练数据才能运行,我认为这必须

  • 问题内容: 在Java中,如何获取byte []数组并从数组中删除前16个字节?我知道我可能必须通过将阵列复制到新阵列中来执行此操作。任何例子或帮助将不胜感激。 问题答案: 参见Java库中的类:

  • 问题内容: 给定任意实例,包括运行时生成的实例(磁盘上没有文件),是否有任何方法获取类字节? 问题答案: 通常,这是不可能的。在加载类时,JVM会解析其字节码并将其转换为内部表示形式。此后,JVM可以随意忘记原始字节码,这就是HotSpot JVM真正发生的情况。 但是,对于某些黑客,可以检查内部类表示并将其转换回有效的类文件(尽管它将与原始字节码不同)。在HotSpot JVM中,该过程用于重新

  • 问题内容: 我正在尝试检测Java字节码。 我想识别 java循环 的 进入和退出 ,但是我发现识别循环非常具有挑战性。我花了很多时间研究 ASM 和 开源反编译器 (我一直认为自己必须始终解决此问题),但是我的想法很短。 我正在扩充/扩展的工具正在使用ASM,因此理想情况下, 我想知道如何通过ASM在Java中检测不同循环结构的进入和退出 。但是,我也欢迎关于一个好的开源反编译器的建议,因为显然

  • 问题内容: 所以-我有一个需要a 作为输入的第三方库。我有一个。 我不想将字节写入磁盘..我想将其保留在内存中。我如何从提供的内容创建一个想法(无需写入磁盘)? 问题答案: 抱歉,不可能。除非您具有RAM磁盘,否则File本质上是磁盘上的实体-但这不是您可以用Java创建的东西。 这正是API不应该基于File对象(或过载以接受InputStream)的原因。