1

私は穀物に非常に慣れていないので、(おそらく簡単な)質問があります:

(XML) アーカイブ内のオブジェクトの数がわからない場合、複数のオブジェクトを逆シリアル化する方法はありますか?

私は次のようなものを試しました:

std::ifstream is("c:\\data.xml");
cereal::XMLInputArchive archive(is);

while (is.good() && !is.eof())
{               
    try{
        ObjectIn oIn;
        archive(oIn);
        objectList.push_back(oIn);
    }
    catch (exception e){
    }
}

XML ファイルに 3 つのオブジェクトがあり、受け取った XML にオブジェクト番号が含まれていないとします。したがって、私のコードでは、最初の 3 回の繰り返しは問題ありませんが、4 回目では「CerealTest.exe の 0x0035395E で未処理の例外: 0xC0000005: アクセス違反の読み取り場所 0x00000018」が生成されます。

何か提案はありますか?

4

1 に答える 1

4

あなたの質問に答える前に、ひとつ質問させてください: 不明な数のアイテムをシリアライズしている場合、それらのアイテムを可変数のアイテムを保持するように設計されたコンテナに入れてみませんか? を使用しstd::vectorて保存し、ObjectIn任意の数を簡単に処理できます。コードは次のようになります。

std::vector<MyObjects> vec;
{
  cereal::XMLInputArchive ar("filename");
  ar( vec );
} // get in the habit of using cereal archives in an RAII fashion

上記はシリアル化された任意の数のオブジェクトで機能します。最初にシリアルが XML を生成したと仮定します。XML コードでベクターから要素を追加または削除することもでき、正しく機能します。


不明な数のオブジェクトを読み取り、可変数の要素を保持するように設計されたコンテナーに配置しないことに固執している場合は、次のようにすることができます (ただし、これは良い考えではないことに注意してください。実際に変更を試みる必要があります)。あなたのシリアライゼーション戦略であり、これを行わないでください):

{
  cereal::XMLInputArchive ar("filename");
  try
  {
    while( true )
    {
      ObjectIn ob;
      ar( ob );
      objectList.push_back(oIn);
    }
  catch( ... )
  { }
}

繰り返しになりますが、これは基本的にシリアル化戦略の問題であり、アイテムの数がわからない場合は、アラカルトのアイテムではなくコンテナーをシリアル化する必要があることを強調します。上記のコードは、それ以外の読み取りを処理することはできません。例外が発生するまで、盲目的に読み取りを試みるだけです。オブジェクトが何らかの命名パターンに従っている場合は、名前と値のペア ( cereal::make_nvp) を使用して名前で取得できます。

于 2014-04-05T05:19:15.473 に答える