我将数据库单元格中的一系列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-object结尾指示符(类似于文本文件中使用的\ n或EOF指示符)。这样即使记录被破坏,其他记录也是可以恢复的。
如果是这样,在每个pbf结束时添加记录结束指标的建议方法是什么。
在Visual Studio 2010上使用protobuf-netv2和C#。
由于 和Manish
答案 0 :(得分:3)
如果您通过Serialize
/ Deserialize
使用vanilla消息,则no:这不是规范的一部分(因为格式设计为可附加的)。
但是,如果使用SerializeWithLengthPrefix
,它将在消息开头转储长度;然后它会事先知道预期有多少数据。您使用DeserializeWithLengthPrefix
反序列化,如果没有足够的数据,它会大声抱怨。然而!如果你有额外的数据,它不会抱怨,因为太设计为可附加的。
就Jon的回复而言,*WithLengthPrefix
方法的默认用法是,根据存储的数据与Jon建议完全相同;它假装有一个包装器对象并且相应地表现。不同之处是:
这两个“可附加”的区别在于第一个意味着“合并为单个对象”,其中第二个意思是“我期望多个记录”。
无关的建议:
s.Write(m.GetBuffer(), 0, m.ToArray().Length);
应该是:
s.Write(m.GetBuffer(), 0, (int)m.Length);
(无需创建额外的缓冲区)
答案 1 :(得分:2)
(注意:我对protobuf-net本身了解不多,但这通常适用于Protocol Buffer消息。)
通常,如果你想记录多条消息,那么只需要输入一个“包装”消息 - 将“真实”消息作为重复字段。然后,每个“真实”消息的长度前缀为协议缓冲区的自然线格式。
这当然不会检测到腐败 - 但说实话,如果数据库最终被破坏,你就会遇到更大的问题。您可能会检测损坏,例如通过保持散列以及每条记录......但是您需要考虑在长度前缀内或散列本身内发生损坏的可能性。想想你想要在这里实现的目标 - 你想要防范的场景,以及你需要什么级别的恢复。