c# - 如何在 C# 中将 .proto 文件解析为 FileDescriptor?

标签 c# protobuf-net

我的目标与 this issue on github 中所述完全相同:

how to read an existing .proto file and get a FileDescriptor from it

我无法使用建议的“解决方法”,原因有两个:

  • 我有“普通”.proto 文件,即:
  • 我不想将协议(protocol)编译器作为外部应用程序调用。

According to Marc这可以通过 protobuf-net 实现图书馆:

Without a compiled schema, you would need a runtime .proto parser. [...] protobuf-net includes one (protobuf-net.Reflection)

我找到了Parsers.cs

谢谢马克,但是我该如何使用/执行此操作? 这是正确的切入点吗? 某处有一个最小的工作示例吗?

最佳答案

var set = new FileDescriptorSet();
set.Add("my.proto", true);
set.Process();

这就是你所需要的;请注意,如果您想提供实际内容(而不是让库进行文件访问),则有一个可选的 TextReader 参数。如果您需要进口:

set.AddImportPath(...);

调用 Process 后,.Files 应与每个文件的 .MessageTypes 一起填充,等等。

有关更完整的示例:

var http = new HttpClient();
var proto = await http.GetStringAsync(
 "https://raw.githubusercontent.com/protocolbuffers/protobuf/master/examples/addressbook.proto");

var fds = new FileDescriptorSet();
fds.Add("addressbook.proto", true, new StringReader(proto));
fds.Process();
var errors = fds.GetErrors();
Console.WriteLine($"Errors: {errors.Length}");

foreach(var file in fds.Files)
{
    Console.WriteLine();
    Console.WriteLine(file.Name);

    foreach (var topLevelMessage in file.MessageTypes)
    {
        Console.WriteLine($"{topLevelMessage.Name} has {topLevelMessage.Fields.Count} fields");
    }
}

哪些输出:

addressbook.proto
Person has 5 fields
AddressBook has 1 fields

google/protobuf/timestamp.proto
Timestamp has 2 fields

请注意,您不必提供 timestamp.proto 或其导入路径 - 该库嵌入了许多常见导入,并自动使它们可用。

(每个文件都是一个 FileDescriptorProto;逻辑解析操作中的文件组是 FileDescriptorSet - 它是 descriptor.proto 使用的根对象;请注意如果您需要编译/二进制模式,则此图中的所有对象也是 protobuf 可序列化的)

关于c# - 如何在 C# 中将 .proto 文件解析为 FileDescriptor?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62575156/

相关文章:

基于接口(interface)的 Protobuf-net 序列化

protobuf-net - Protobuf GTFS 实时无效线型

compact-framework - 为紧凑框架预编译 protobuf-net 类型模型

c# - 添加依赖于第一个类型的第二个类型时出错

c# - 为什么这个 LINQ 查询没有按预期工作?

c# - 如何在 mvc3 asp.net 中发送文本框值作为表单提交的参数

protobuf-net - 是否可以使用 protobuf-net Serializer 并同时使用相应的 *.proto 文件?

c# - List<T> 是链表吗?

c# - 通用工作计划。将文件从 FileOpenPicker 复制到本地存储

deserialization - protobuf-net 的大文件反序列化