【问题标题】:Protobuf-net Serialize creating hex charactersProtobuf-net 序列化创建十六进制字符
【发布时间】:2015-04-01 03:43:49
【问题描述】:

我目前正在做一个 POC 来证明 Protobuf-net 比原生 C# 序列化器更快。但我遇到了一个错误?关于序列化响应。

这是错误

本机结果

<?xml version="1.0"?>
<userInformation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <age>22</age>
  <education>Cavite State University</education>
  <name>Ronald Estacion</name>
  <address>
    <city>Cavite</city>
    <country>PH</country>
    <street>Torjak Street</street>
    <subd>Yari ka ngayon</subd>
  </address>
</userInformation>

原始结果

这是我的代码。

var nativeSerializer = new XmlSerializer(typeof(UserInformation));
var nativeStream = new MemoryStream();
var protoStream = new MemoryStream();
nativeSerializer.Serialize(nativeStream, CreateDetaulUserInformation());
var nativeResult = Encoding.UTF8.GetString(nativeStream.ToArray());
Serializer.Serialize(protoStream, CreateDetaulUserInformation());
var protoResult = Encoding.UTF8.GetString(protoStream.ToArray());

这是 UserInformation 对象。

//[ProtoContract]
[XmlType("address")]
public class Address
{
    //[ProtoMember(1)]
    [XmlElement("city", Order = 1)]
    public string City { get; set; }

    //[ProtoMember(2)]
    [XmlElement("country", Order = 2)]
    public string Country { get; set; }

    //[ProtoMember(3)]
    [XmlElement("street", Order = 3)]
    public string Street { get; set; }

    //[ProtoMember(4)]
    [XmlElement("subd", Order = 4)]
    public string Subdivision { get; set; }
}

//[ProtoContract]
[XmlType("userInformation")]
public class UserInformation
{
    //[ProtoMember(1)]
    [XmlElement("age", Order = 1)]
    public int Age { get; set; }

    //[ProtoMember(2)]
    [XmlElement("education", Order = 2)]
    public string Education { get; set; }

    //[ProtoMember(3)]
    [XmlElement("name", Order = 3)]
    public string Name { get; set; }

    //[ProtoMember(4)]
    [XmlElement("address", Order = 4)]
    public Address Address { get; set; }
}

注意:我也尝试使用ProtoContract 作为属性,但结果相同。 Protobuf-net 也支持XmlType,所以我评论了这些属性。

【问题讨论】:

  • 您的 XML 文件的编码是什么?
  • 您所说的“本机 C# 序列化程序”是 NET XML 序列化程序。输出是 XML(文本)。 ProtoBuf 是一个 binary 序列化器。你在比较苹果和西红柿。不可打印的前导字符是 22(年龄)的序列化二进制表示。一切都按预期工作。将 NET BinaryFormatter 的输出与 ProtoBuf 进行比较,以获得更相似的比较。
  • @Plutonix 如何实现 xml 字符串输出?
  • @DevEstacion base-64 可以在 xml 中传输 - 请注意,这样做会带来不必要的开销,但

标签: c# xml serialization xml-serialization protobuf-net


【解决方案1】:

这是你的错误:

var protoResult = Encoding.UTF8.GetString(protoStream.ToArray());

protobuf 是一个二进制协议;它是 not 文本,特别是不是 UTF8。当输入数据不是 UTF-8 缓冲区时,您正在尝试将 UTF-8 缓冲区解码为字符串。

如果您想将原始byte[] 变成string,那么Convert.ToBase64String 是您的朋友。但如果您可以避免这样做:如果可能,最好将其视为二进制端到端。

作为一个非常小的事情:没有必要在这里调用ToArray() - 这会强制一个额外的数组副本。如果可能,使用GetBuffer() 结合 .Length(底层缓冲区过大);即

string base64 = Convert.ToBase64String(
    protoStream.GetBuffer(), 0, (int)protoStream.Length);

【讨论】:

  • 问题是我们有一个遗留的 web 服务,它接受 Xml 请求和 Xml 响应,所以我正在寻找一种方法来更快地对 xmls 进行序列化/反序列化
  • @DevEstacion protobuf-net 不是 xml 序列化程序;它说“protobuf”
  • ♦ 正如我所想,我只是想知道是否可以在反序列化和序列化中使用它的速度作为 xml。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-20
  • 2014-12-20
  • 2022-01-24
  • 2011-08-05
  • 1970-01-01
  • 1970-01-01
  • 2016-06-08
相关资源
最近更新 更多