.net protobuf net裸最小值,用于编码字符串和数字
我已经浏览了Marc Gravel和Jon Skeet的protobuf net,但是他们似乎做的比我要查找的要多,而且我在运行他们的代码时遇到了问题(获取System&System.Xml引用问题),但我正在使用他们在code.google.com上的最新版本 通常我会查看他们的测试,但是Jon的测试使用了太多的测试助手,这让人很难理解,Marc将OO和对象依赖性发挥到了极致。除非我完全遗漏了一些东西,我可能是 我正在寻找一个或另一个项目中的最小类来编码字符串或数字(int、int16、in64、double、float、decimal等)。我不想对类或嵌套类进行编码。我也不想找人写这一切。我希望有人能给我指出做这件事的最基本的类/方法,或者是关于如何实现这一点的实际细节,而不用花很多力气(除了使用Jon&Marc实现的东西或者仅仅参考Google协议缓冲区文档) 基本上,我在寻找一些简单的东西:.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
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是否适合,因为您不需要对象序列化程序,但是:
包装了一个流,并提供了您想要的工具;格式与protobuf无关,但应该可以工作。请注意,对于名称/值对,您只需编写名称,然后再编写值BinaryWriter
- 如果你真的想把protobuf放在这里的某个地方,protobuf NetV2有
,它是基本的“我写值”,而不是对象;但是请注意,它不处理字段名,因为这不符合protobuf规范(使用数字标记)ProtoWriter
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:它编码更密集,但是:是的,稍微(编码!=压缩)