我通过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);
};
}
}
答案 0 :(得分:1)
如果您希望将自己的序列化视为BitConverter。
在我找到proto buf之类的东西之前,这是我用于序列化的基本构建块。它具有进出所有值类型的字节数组的方法。将它包装成类似示例代码的类应该相当容易。
对于字符串,您需要使用编码器。
var encoding = new System.Text.UTF8Encoding(); var bytes = encoding.GetBytes(str);
答案 1 :(得分:1)
不完全确定protobuf是如何适应的,因为你不需要对象序列化器,但是:
BinaryWriter
包裹一个流,并提供您想要的工具;格式与protobuf无关,但应该有效。请注意,对于名称/值对,您只需编写名称,然后写入值ProtoWriter
这是基本的“我写的价值”,而不是对象;但请注意,它不处理字段名称,因为它不适合protobuf规范(使用数字标记)显然每个都有双胞胎; BinaryReader
和ProtoReader
。
就个人而言,我认为你会发现从对象的角度思考会更方便。但你可以自己控制它,就像我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);
}