4

一連の protobuf-net オブジェクトをデータベース セルに長さのプレフィックス付き protobuf-net オブジェクトの Byte[] として保存しています。

//retrieve existing protobufs from database and convert to Byte[]
object q = sql_agent_cmd.ExecuteScalar();
older-pbfs = (Byte[])q;

// serialize the new pbf to add into MemoryStream m
//now write p and the new pbf-net Byte[] into a memory stream and retrieve the sum

var s = new System.IO.MemoryStream();
s.Write(older-pbfs, 0, older-pbfs.Length);
s.Write(m.GetBuffer(), 0, m.ToArray().Length); // append new bytes at the end of old
Byte[] sum-pbfs = s.ToArray();

//sum-pbfs = old pbfs + new pbf. Insert sum-pbfs into database

これはうまくいきます。私の懸念は、データベースがわずかに破損した場合にどうなるかです。どのバイトが長さのプレフィックスであるかを知ることができなくなり、セルの内容全体を破棄する必要があります。ある種の pbf オブジェクト終了インジケータ (テキスト ファイルで使用される \n または EOF インジケータのようなもの) も使用することをお勧めします。これにより、レコードが破損した場合でも、他のレコードは回復可能になります。

もしそうなら、各 pbf の最後に記録終了インジケータを追加するための推奨される方法は何ですか?

Visual Studio 2010 で protobuf-netv2 と C# を使用します。

ありがとうマニッシュ

4

2 に答える 2

3

Serialize/を介してバニラ メッセージを使用する場合Deserialize、いいえ: それは仕様の一部ではありません (形式が追加可能になるように設計されているため)。

ただし、 を使用するSerializeWithLengthPrefixと、メッセージの先頭で長さがダンプされます。その後、予想されるデータ量を事前に知ることができます。で逆シリアル化しDeserializeWithLengthPrefix、十分なデータがない場合は大声で文句を言います。でも!これも追加できるように設計されているため、余分なデータがあっても問題はありません。

Jon の返信によると、メソッドのデフォルトの使用*WithLengthPrefix法は、 Jon が提案するものとまったく同じように格納されたデータに関するものです。ラッパー オブジェクトが存在するふりをして、それに応じて動作します。違いは次のとおりです。

  • ラッパーオブジェクトは実際には存在しません
  • 「withlengthprefix」メソッドは、後のデータを同じオブジェクトにマージするのではなく、単一の発生後に明示的に停止します(たとえば、複数の個別のオブジェクトを単一のファイルに送信したり、単一のソケットをダウンさせたりする場合に役立ちます)

ここでの 2 つの「追加可能」の違いは、1 つ目は「1 つのオブジェクトにマージする」ことを意味し、2 つ目は「複数のレコードを期待する」ことを意味することです。

無関係な提案:

s.Write(m.GetBuffer(), 0, m.ToArray().Length);

次のようにする必要があります。

s.Write(m.GetBuffer(), 0, (int)m.Length);

(余分なバッファを作成する必要はありません)

于 2012-05-15T19:27:55.833 に答える
2

(Note: I don't know much about protobuf-net itself, but this is generally applicable to Protocol Buffer messages.)

Typically if you want to record multiple messages, it's worth just putting a "wrapper" message - make the "real" message a repeated field within that. Each "real" message will then be length prefixed by the natural wire format of Protocol Buffers.

This won't detect corruption of course - but to be honest, if the database ends up getting corrupted you've got bigger problems. You could potentially detect corruption, e.g. by keeping a hash along with each record... but you need to consider the possibility of the corruption occurring within the length prefix, or within the hash itself. Think about what you're really trying to achieve here - what scenarios you're trying to protect against, and what level of recovery you need.

于 2012-05-15T19:04:33.043 に答える