【问题标题】:How to ignore wrong fields when parsing a text-format protobuf message解析文本格式的 protobuf 消息时如何忽略错误的字段
【发布时间】:2016-01-20 03:02:47
【问题描述】:

我用 c++ 中的错误字段模拟了一个文本格式的文件解析。

我的简单测试 .proto 文件:

$ cat settings.proto
package settings;
message Settings {
   optional int32  param1 = 1;
   optional string param2 = 2;
   optional bytes  param3 = 3;
}

我的文本格式文件:

$ cat settings.txt
param1: 123
param: "some string"
param3: "another string"

我正在使用 google::protobuf::TextFormat::Parser: 解析文件:

#include <iostream>
#include <fcntl.h>
#include <unistd.h>
#include <fstream>
#include <google/protobuf/text_format.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>

#include <settings.pb.h>

using namespace std;

int main( int argc, char* argv[] )
{
    GOOGLE_PROTOBUF_VERIFY_VERSION;

    settings::Settings settings;

    int fd = open( argv[1], O_RDONLY );
    if( fd < 0 )
    {
        cerr << " Error opening the file " << endl;
        return false;
    }

    google::protobuf::io::finputStream finput( fd );
    finput.SetCloseOnDelete( true );

    google::protobuf::TextFormat::Parser parser;
    parser.AllowPartialMessage( true );

    if ( !parser.Parce( &finput, &settings ) )
    {
        cerr << "Failed to parse file!" << endl;
    }

    cout << settings.DebugString() << endl;

    google::protobuf::ShutdownProtobufLibrary();

    std::cout << "Exit" << std::endl;
    return true;
}

我为解析器将 AllowPartialMessage 设置为 true。所有字段都是可选的。 但目前 Parse 在第一个错误字段后停止解析。并且解析后“设置”只包含一个第一个字段。

有没有办法通知失败并继续解析另一个正确的字段?

【问题讨论】:

  • 你不应该尝试它。垃圾进,垃圾出。

标签: c++ parsing protocol-buffers


【解决方案1】:

文本格式解析器不允许未知字段。文本格式用于与人类交流,人类会打错字。重要的是检测这些错别字,而不是默默地忽略它们。

通常,忽略未知字段的原因是为了向前兼容:然后您的程序可以(部分)理解针对具有新字段的协议的未来版本编写的消息。有两个我经常看到的特殊用例:

  • 以文本格式进行机器对机器通信的系统。我建议不要这样做。相反,请使用二进制格式,或者如果您真的希望机器对机器的通信是文本的,请使用 JSON。

  • 人类编写文本格式配置文件然后将其分发到生产中可能较旧的服务器的系统。在这种情况下,我建议使用在人类桌面上运行的工具将文本格式的 protobuf “预编译”为二进制文件,然后仅将 binary 消息发送到生产服务器。本地工具可以轻松保持最新状态,并且能够告诉人类用户是否拼错了字段名称。

【讨论】:

  • 感谢您的回答。我们想以 protobuf 格式存储应用程序的设置。应用程序将更改设置。但我们也想手动更改它们以进行调试。这就是我们选择文本格式的原因。文本格式解析器不允许未知字段对我们来说是正常的。我正在检查不同的场景。更常见的情况是应用程序忽略错误(仅显示警告)并继续加载其他设置。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-16
相关资源
最近更新 更多