2016-01-20 14 views
5

C++の間違ったフィールドで解析するテキスト形式のファイルをシミュレートします。テキスト形式のprotobufメッセージを解析するときに間違ったフィールドを無視する方法

ファイル.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" 

を私はグーグル::いるProtobuf ::れるTextFormat ::パーサーでファイルを解析しています

#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は最初の間違ったフィールドの後に解析を停止します。また、解析後、「設定」には最初のフィールドが1つしかありません。

失敗したことを通知し、別の正しいフィールドを解析し続ける方法はありますか?

+0

試してはいけません。ゴミ入れ、ゴミ出し。 – EJP

答えて

3

テキスト形式のパーサーでは未知のフィールドは許可されません。テキスト形式は人間とのコミュニケーションを目的としており、人間はタイプミスを犯します。これらのタイプミスを静かに無視するのではなく、検出することが重要です。

未知のフィールドを無視する理由は、通常、転送互換性のためです。プログラムは、新しいフィールドでプロトコルの将来のバージョンに対して作成されたメッセージを部分的に理解できます。テキスト形式でのマシン対マシン通信を行う

  • システム:私は多くを参照してください。この2つの特定のユースケースがあります。私はこれに反対することを勧めます。バイナリ形式を使用するか、マシン間の通信をテキスト形式にしたい場合は、JSONを使用してください。

  • 人間がテキスト形式の設定ファイルを書き込んで、それを本番環境の古いサーバに配布するシステム。この場合、人間のデスクトップ上で実行されるツールを使用して、テキスト形式のprotobufをバイナリ形式に「プレコンパイル」してから、バイナリメッセージのみを運用サーバーに送付することをお勧めします。ローカルツールは簡単に最新の状態に保つことができ、ユーザーにフィールド名のスペルが間違っているかどうかを伝えることができます。

+1

お返事ありがとうございます。アプリケーションの設定をprotobuf形式で保存したい。アプリケーションによって設定が変更されます。しかし、デバッグのために手動で変更したいと思っています。テキスト形式を選択する理由です。テキスト形式のパーサーは未知のフィールドを許可しないのは普通です。私はさまざまなシナリオをチェックしています。また、アプリケーションがエラーを無視した場合(警告を表示するだけ)、別の設定をロードし続ける場合、より一般的なケースです。 – dmiry

関連する問題