.net protobuf net裸最小值,用于编码字符串和数字

.net protobuf net裸最小值,用于编码字符串和数字,.net,serialization,c#-3.0,protocol-buffers,.net,Serialization,C# 3.0,Protocol Buffers,我已经浏览了Marc Gravel和Jon Skeet的protobuf net,但是他们似乎做的比我要查找的要多,而且我在运行他们的代码时遇到了问题(获取System&System.Xml引用问题),但我正在使用他们在code.google.com上的最新版本 通常我会查看他们的测试,但是Jon的测试使用了太多的测试助手,这让人很难理解,Marc将OO和对象依赖性发挥到了极致。除非我完全遗漏了一些东西,我可能是 我正在寻找一个或另一个项目中的最小类来编码字符串或数字(int、int16、in6

我已经浏览了Marc Gravel和Jon Skeet的protobuf net,但是他们似乎做的比我要查找的要多,而且我在运行他们的代码时遇到了问题(获取System&System.Xml引用问题),但我正在使用他们在code.google.com上的最新版本

通常我会查看他们的测试,但是Jon的测试使用了太多的测试助手,这让人很难理解,Marc将OO和对象依赖性发挥到了极致。除非我完全遗漏了一些东西,我可能是

我正在寻找一个或另一个项目中的最小类来编码字符串或数字(int、int16、in64、double、float、decimal等)。我不想对类或嵌套类进行编码。我也不想找人写这一切。我希望有人能给我指出做这件事的最基本的类/方法,或者是关于如何实现这一点的实际细节,而不用花很多力气(除了使用Jon&Marc实现的东西或者仅仅参考Google协议缓冲区文档)

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


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);
  };
 }
}

如果您希望自己的序列化角色,请查看

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

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

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

不完全确定protobuf是否适合,因为您不需要对象序列化程序,但是:

  • BinaryWriter
    包装了一个流,并提供了您想要的工具;格式与protobuf无关,但应该可以工作。请注意,对于名称/值对,您只需编写名称,然后再编写值
  • 如果你真的想把protobuf放在这里的某个地方,protobuf NetV2有
    ProtoWriter
    ,它是基本的“我写值”,而不是对象;但是请注意,它不处理字段名,因为这不符合protobuf规范(使用数字标记)
显然每个人都有双胞胎
BinaryReader
ProtoReader

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

下面是一个使用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);
}

我认为ProtoBuf可以压缩数据,但也可以使它能够非常快地读取压缩数据。若BinarySerializer更小并且同样高效,那个么也许我会使用它。问题是我们有一个70年代建立的遗留系统,大多数数据都是字符串值。问题在于,该系统类似于文档数据库(NoSql),当您返回一条记录时,它将返回整个文档(即一条记录)。这个记录可能是巨大的,超过200个字段。我基本上希望在序列化过程中进行压缩,并保存发送的字节。据我所知,ProtoBuff是构建的。@thames
BinarySerializer
不存在;你是说
BinaryFormatter
?或者
BinaryWriter
?这有点重要。重新定义UTF8与unicode,因为它在序列化过程中处理编码,这不重要;一旦它是一个.NET字符串,它就是UTF-16。我认为BinaryWriter是BinaryFormatter和BinaryWriter之间的一个更好的选择。与ProtoBuf相比,这在字节压缩方面是否同样好,或者ProtoBuf的性能和压缩性能是否仍然更好?@thames pedant point:它编码更密集,但是:是的,稍微(编码!=压缩)