Protobuf .Net を使用したデシリアライズについて質問があります。XMLSerializer をそれに置き換えようとしていますが、ファイルから単一のフィールドを逆シリアル化する方法が見つかりません。
ファイルが変更されたかどうかの情報が必要です。これは、保存された構造のフィールドの 1 つです。
それは可能ですか?はいの場合、何か助けを求めることはできますか?
よろしく
Protobuf .Net を使用したデシリアライズについて質問があります。XMLSerializer をそれに置き換えようとしていますが、ファイルから単一のフィールドを逆シリアル化する方法が見つかりません。
ファイルが変更されたかどうかの情報が必要です。これは、保存された構造のフィールドの 1 つです。
それは可能ですか?はいの場合、何か助けを求めることはできますか?
よろしく
ほとんどの場合、率直に言って、全体をデシリアライズするだけで済みます。高速になるなどです。ただし、本当に制限したい場合は、いくつかのオプションがあります。
最も簡単な方法は、必要な情報だけを含む小さなモデルを作成することです。したがって、元のモデルに 46 のフィールドがあり、そのうちの 5 つはコレクションなどですVersion
が、フィールド 12 にあるものだけが必要な場合は、次のようになります。
[ProtoContract]
public class InsertNameHere {
[ProtoMember(12)]
public int Version {get;set;}
}
それを逆シリアル化します:
var obj = Serializer.Deserialize<InsertNameHere>(source);
int version = obj.Version;
protobuf-net は契約ベースであるため、これは機能します。十分に似ている限り、まったく同じタイプである必要はありません。ただし、より高度なアプローチは、次を使用することProtoReader
です。
int version = 0;
using (var reader = new ProtoReader(source, RuntimeTypeModel.Default, null))
{
int field;
bool keepReading = true;
while ((field = reader.ReadFieldHeader()) > 0 && keepReading)
{
switch (field)
{
case 12:
version = reader.ReadInt32();
// STOP LOOPING (leaves the stream partly-read)
keepReading = false;
break;
default:
reader.SkipField();
break;
}
}
}
上記を使用する理由は、検索を早期に停止できるためです。つまり、フィールド 12 を見つけたらすぐに、ファイルの残りを処理せずにリーダーを強制終了できます。通常、2 番目の方法は、データが大きいことがわかっていて、あまりデータを必要としない場合にのみ使用します。
技術的には protobuf は追加可能な形式であるため、理論的にはファイルの最後に別の「フィールド 12」が存在する可能性があるという点で、わずかな落とし穴があります。仕様では、「最後の値が勝つ」ため、上記の短絡は(理論的には)別の答えを与える可能性があります。でも!これが起こる可能性は非常に低く、通常、追加されたメッセージを利用しているかどうかはわかります。これは、ほとんどの人には当てはまりません。