protobuf-net最小编码字符串和数字

时间:2011-04-08 02:49:04

标签: .net serialization c#-3.0 protocol-buffers

我通过Marc Gravell和Jon Skeet查看了protobuf-net但是他们似乎比我正在寻找的更多,而且我在运行他们的代码时遇到问题(获得System& System。 Xml参考问题)但是我正在使用他们最新的code.google.com。

通常情况下,我会查看他们的测试,但Jon的测试使用了很多测试助手很难遵循,而Marc已经将OO和对象依赖性调到了最大值。除非我完全遗漏了某些东西,否则我可以。

我正在寻找一个或另一个项目中的最小类来编码字符串或数字(int,int16,in64,double,float,decimal等)。我不想编码类或嵌套类。我也不是在找人写这一切。我希望有人可以指出我做到这一点的最低级别的方法/方法,或者指出如何实现这一点的实际细节而不需要付出太多努力(除了使用Jon& Marc实施或仅仅参考Google Protocols Buffer文档)。

基本上我正在寻找一些简单的东西:


public class test {

 public void serialize_test() {
  using(var ms = new MemoryStream())
  {
   var str = "This is a test!";
   Serializer.Serialize(ms, str);
   byte[] raw = ms.ToArray();
   ms.Position = 0;
   var obj = Serializer.Deserialize(ms);
   Assert.AreEqual(str, (string)obj);
  };
 }

 public void serialize_to_field_test() {
  using(var ms = new MemoryStream())
  {
   var str = "This is a test!";
   Serializer.SerializeField(ms, str, 1);
   Serializer.SerializeField(ms, "field 2 value", 2);
   Serializer.SerializeField(ms, "field 3 value", 3);
   Serializer.SerializeField(ms, 4, 4);
   byte[] raw = ms.ToArray();
   ms.Position = 0;
   // probably should use an iterator pattern
   var field1 = Serializer.DeserializeField(ms, 1);
   var field2 = Serializer.DeserializeField(ms, 2);
   var field3 = Serializer.DeserializeField(ms, 3);
   var field4 = Serializer.DeserializeField(ms, 4);
   Assert.AreEqual(str, (string)field1);
   Assert.AreEqual("field 2 value", (string)field2);
   Assert.AreEqual("field 3 value", (string)field3);
   Assert.AreEqual(4, (int)field4);
  };
 }
}

2 个答案:

答案 0 :(得分:1)

如果您希望将自己的序列化视为BitConverter

在我找到proto buf之类的东西之前,这是我用于序列化的基本构建块。它具有进出所有值类型的字节数组的方法。将它包装成类似示例代码的类应该相当容易。

对于字符串,您需要使用编码器。

var encoding = new System.Text.UTF8Encoding();  var bytes = encoding.GetBytes(str);

答案 1 :(得分:1)

不完全确定protobuf是如何适应的,因为你不需要对象序列化器,但是:

  • BinaryWriter包裹一个流,并提供您想要的工具;格式与protobuf无关,但应该有效。请注意,对于名称/值对,您只需编写名称,然后写入值
  • 你真的想在这里的protobuf,protobuf-net v2有ProtoWriter这是基本的“我写的价值”,而不是对象;但请注意,它不处理字段名称,因为它不适合protobuf规范(使用数字标记)

显然每个都有双胞胎; BinaryReaderProtoReader

就个人而言,我认为你会发现从对象的角度思考会更方便。但你可以自己控制它,就像我here一样。

以下是使用alpha dll的示例:

using (var ms = new MemoryStream())
{
    var str = "This is a test!";
    using (var writer = new ProtoWriter(ms, null))
    {
        ProtoWriter.WriteFieldHeader(1, WireType.String, writer);
        ProtoWriter.WriteString(str, writer);
        ProtoWriter.WriteFieldHeader(2, WireType.String, writer);
        ProtoWriter.WriteString("field 2 value", writer);
        ProtoWriter.WriteFieldHeader(3, WireType.String, writer);
        ProtoWriter.WriteString("field 3 value", writer);
        // use Variant if never negative
        ProtoWriter.WriteFieldHeader(4, WireType.SignedVariant, writer);
        ProtoWriter.WriteInt32(4, writer);
    }
    byte[] raw = ms.ToArray();
    ms.Position = 0;
    string field1 = "", field2 = "", field3 = "";
    int field4 = 0;
    using (var writer = new ProtoReader(ms, null))
    {
        int field;
        while((field = writer.ReadFieldHeader()) > 0)
        {
            switch (field)
            {
                case 1: field1 = writer.ReadString(); break;
                case 2: field2 = writer.ReadString(); break;
                case 3: field3 = writer.ReadString(); break;
                case 4: // remove the Hint() if using Variant
                    writer.Hint(WireType.SignedVariant);
                    field4 = writer.ReadInt32(); break;
            }
        }
    }
    Console.WriteLine(field1);
    Console.WriteLine(field2);
    Console.WriteLine(field3);
    Console.WriteLine(field4);
}