标签: protobuf-net

使用带有标志枚举的ProtoBuf-Net时出错

在使用ProtoBuf-Net并序列化枚举属性时,枚举设置为[FlagsAttribute],在序列化由多个标志组成的枚举值时收到以下错误消息.

错误是:值(MyEnum.MyValue)没有属性MyProperty的线表示

MyEnum在哪里:

[Flags]
public Enum MyEnum
{
    MyValue = 0,
    MyValue1 = 1,
    MyValue2 = 2,
    MyValue4 = 4,
    MyValue8 = 8,
}
Run Code Online (Sandbox Code Playgroud)

MyProperty = MyEnum.MyValue2 | MyEnum.MyValue4;
Run Code Online (Sandbox Code Playgroud)

似乎是protobuf-net中的一个bug?

c# protobuf-net

5
推荐指数
1
解决办法
2162
查看次数

为什么我必须使用[ProtoInclude]?

我已经阅读了很多关于protobuf-net中继承功能的问题.我只是想知道如果我可以像使用[ProtoContract],[ProtoMember]一样使用[DataContract],[DataMember].为什么我不能使用[KnowType]而不是使用[ProtoInclude]?

我提出这个问题是因为我已经将[DataContract],[DataMember]用于protobuf-net的序列化.没有必要添加"Protobuf-net".它只使用"System.Runtime.Serialization".

但是......现在如果我的类需要从某个类继承,我是否必须为[ProtoInclude]属性添加"Protobuf-net"?例如,

using System.Runtime.Serialization;
namespace test
{

[DataContract]
/// [KnowType(typeof(SomeClass))]
/// or
/// [ProtoInclude(100,typeof(SomeClass))]
public class BaseClass
{
   //...
   [DataMember(Order=1)]
   public string BlahBlahBlah {get; set;}
}

[DataContract]
public class ChildClass1 : BaseClass
{
   //...
   [DataMember(Order=1)]
   public string BlahBlahBlah {get; set;}
}
}// end namespace
Run Code Online (Sandbox Code Playgroud)

最后,我想知道我是否有100个子类,我不会疯狂地在基类中添加100个[ProtoInclude]标签吗?

感谢您提供任何帮助

VEE

protobuf-net

5
推荐指数
1
解决办法
3719
查看次数

在protobuf-net中,可以基于基本类型对消息进行部分反序列化

在protobuf-net中,是否可以基于基本类型对消息进行反序列化?

在我的系统中,我有一个继承层次结构,其中每个消息都从MessageBase继承。MessageBase具有uint MessageType。理想情况下,我只想反序列化MessageBase并检查它是否是我感兴趣的MessageType,然后我就可以丢弃该消息或做出反序列化实际消息的决定。这是为了节省反序列化的成本(我有一个CPU周期预算和大量要处理的消息)。

用法示例如下所示。

非常感谢。

 MessageBase msgBase = ..deserialize; 

  if(msgBase.MessageType = 1)//1 is the Tick msg type
  {
     Tick tick = ..deserialize actual msg;
     //do something with tick
   }
  //throw away msgBase 

[ProtoContract,ProtoInclude(1, typeof(Tick))]
public class MessageBase
{
    protected uint _messageType;

    [ProtoMember(1)]
    public uint MessageType
    {
        get { return _messageType; }
        set{ _messageType = value;}
    }
}

[ProtoContract]
public public class Tick : MessageBase
{
    private int _tickId;
    private double _value;

    public Tick()
    {
        _messageType = 1;
    }

    [ProtoMember(1)]
    public …
Run Code Online (Sandbox Code Playgroud)

c# protocol-buffers protobuf-net

5
推荐指数
1
解决办法
1163
查看次数

快速随机访问二进制文件,但也可以在需要时顺序访问.怎么布局?

我有大约10亿个数据集,它们有一个DatasetKey,每个数据集有1到5 000 000个子条目(一些对象),平均值大约是100,但有很多胖尾巴.

写入数据后,数据不会更新,只会读取数据.

我需要通过DatasetKey读取数据并执行以下操作之一:
获取子条目数
获取前1000个子条目(最大值小于1000)
获取前5000个子条目(最大值小于5000)
获取前100000个子条目(最大值如果小于100000)
获取所有子条目

每个子条目的大小约为20字节到2KB(平均450字节).

我想要使​​用的布局如下:

我创建了一个大小至少为5MB的文件.
每个文件至少包含一个DatasetKey,但如果文件仍然小于5MB,我添加新的DatasetKeys(带子条目),直到我超过5 MB.
首先,我存储一个标题,说明哪些文件偏移我会找到什么样的数据.
此外,我计划使用协议缓冲区存储序列化包.
前1000个条目的一个包,
一个用于接下来的4000个条目,
一个用于接下来的95000个条目,
一个用于下一个剩余的条目.

我将文件大小存储在RAM中(将所有标题存储在我使用的机器上所需的大量RAM中).当我需要访问特定的DatasetKey时,我在RAM中查找我需要的文件.然后我从RAM中获取文件大小.当文件大小约为5MB或更小时,我会将整个文件读入内存并进行处理.如果它超过5MB,我将只读取第一个xKB来获取标题.然后我从磁盘加载我需要的位置.

这听起来怎么样?这完全是胡说八道吗?还是一个好方法?

使用这个设计我有以下几点:

我想将我的数据存储在一个自己的二进制文件而不是数据库中,以便将来更容易备份和处理文件.
我会使用postgresql,但我想出存储二进制数据会使postgresqls-toast不止一次寻求访问数据.
为每个DatasetKey存储一个文件需要太多时间将所有值写入磁盘.
数据在RAM中计算(因为并非整个数据在RAM中同时拟合,它是以块为单位计算的).
5MB的文件大小只是一个粗略的估计.

你说什么?提前谢谢你的帮助!

编辑

更多背景资料:

DatasetKey的类型为ulong.

子条目(有不同的类型)大部分时间如下:

public struct ChildDataSet
{
    public string Val1;
    public string Val2;
    public byte Val3;
    public long Val4;
}
Run Code Online (Sandbox Code Playgroud)

我无法确切地知道访问了哪些数据.计划是用户可以访问特定DatasetKeys的前1000,5000,100000或所有数据.根据他们的设置.

我希望尽可能降低响应时间并尽可能少地使用磁盘空间.

@Regarding随机访问(Marc Gravells问题):

我不需要访问元素号.123456用于特定的DatasetKey.

当在一个文件中存储多个DatasetKey(带有子条目)时(我将其设计为不创建大量文件的方式),我需要随机访问该文件中特定DatasetKey的前1000个条目,或者第一个5000(所以我会阅读1000和4000包).

我只需要访问以下有关一个特定DatasetKey(uint)的内容:
1000个子条目(或所有子条目,如果小于1000)
5000个子条目(或所有子条目,如果小于5000)
100000个子条目(或所有子条目,如果小于100000)
所有子条目

我提到的所有其他事情只是一个设计尝试从我:-)

编辑,在一个类中流式传输一个列表?

public class ChildDataSet
{
    [ProtoMember(1)]
    public List<Class1> Val1;
    [ProtoMember(2)]
    public List<Class2> Val2;
    [ProtoMember(3)]
    public List<Class3> Val3; …
Run Code Online (Sandbox Code Playgroud)

c# binaryfiles protocol-buffers protobuf-net

5
推荐指数
1
解决办法
3041
查看次数

protobuf-net v2需要DataMember(Order = n)注释吗?

简单的实验:我从Northwind创建了一个实体模型,发现生成的类在不添加Order属性的情况下不适用于protobuf-net v2 .有没有办法让实体代码生成器添加Order,或者有没有办法让protobuf-net无需工作Order

我必须改变

[DataMemberAttribute()]
Run Code Online (Sandbox Code Playgroud)

[DataMemberAttribute(Order=1)]

NorthwindEntities e = new NorthwindEntities();

using(var file = File.Create("customers.bin"))
{
    Serializer.Serialize(file, e.Customers);
}
Run Code Online (Sandbox Code Playgroud)

protobuf-net

5
推荐指数
1
解决办法
2663
查看次数

protobuf-net:检测到可能的递归

我尝试序列化对象图(不是很深)时遇到异常.有意义的部分是这样的:

[ERROR]致命的未处理异常:ProtoBuf.ProtoException:可能的递归检测(偏移量:5级):ProtoBuf.ProtoWriter.CheckRecursionStackAndPush(object)<0x00127>处的ProtoBuf.ProtoWriter.StartSubItem(对象,ProtoBuf.ProtoWriter) ,bool)<0x0002f>

该图表示文件/目录结构,我的模型(简化)如下所示:

[ProtoContract] 
[ProtoInclude(100, typeof(PackageDirectory))]
[ProtoInclude(200, typeof(PackageFile))]
public abstract class PackageMember
{
   [ProtoMember(1)] 
   public virtual string Name { get; protected set; }

   [ProtoMember(2, AsReference=true)] 
   public PackageDirectory ParentDirectory { get; protected set; }  
}

[ProtoContract]
public class PackageDirectory : PackageMember
{
   [ProtoMember(3)]
   private Dictionary<string, PackageMember> _children;

   public PackageDirectory()
   {
      _children = new Dictionary<string, PackageMember>();
   }

   public PackageDirectory (string name, PackageDirectory parentDirectory)
      : this()
   {
      this.ParentDirectory = parentDirectory;
      this.Name = name;         
   }

   public void Add (PackageMember member)
   {
      _children.Add(member.Name, member); …
Run Code Online (Sandbox Code Playgroud)

c# recursion serialization protobuf-net

5
推荐指数
1
解决办法
2390
查看次数

如何从WCF服务返回流?

我正在玩protobuf-net和WCF.这是我创建的代码:

public class MobileServiceV2
{
    [WebGet(UriTemplate = "/some-data")]
    [Description("returns test data")]
    public Stream GetSomeData()
    {
        WebOperationContext.Current.OutgoingResponse.ContentType = "application/x-protobuf";

        var ms = new MemoryStream();
        ProtoBuf.Serializer.Serialize(ms, new MyResponse { SomeData = "Test data here" });
        return ms;
    }
}

[DataContract]
public class MyResponse
{
    [DataMember(Order = 1)] 
    public string SomeData { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

当我看到Fiddler时 - 我可以看到正确的传出内容类型,并且看起来都很好,但我得到了空洞的回应.IE提示下载文件,此文件为空.序列化器无法正常工作吗?或者我只是不做对吗?

编辑:

我在方法中添加了以下代码,是的,它正确序列化.我如何从WCF返回流有什么问题..

using (var file = File.Create("C:\\test.bin"))
        {
            Serializer.Serialize(file, new MyResponse { SomeData = "Test data here" });
        }
Run Code Online (Sandbox Code Playgroud)

.net wcf stream protobuf-net

5
推荐指数
1
解决办法
9376
查看次数

nuget错误在便携式库上安装protobuf-net

我正在尝试在便携式类库中安装protobuf-net(2.0.0.602),我似乎无法让它工作.我收到此错误:

PM> install-package protobuf-net
'protobuf-net 2.0.0.602' already installed.
install-package : Could not install package 'protobuf-net 2.0.0.602'. You are trying to install this package into a project that targets '.NETPortable,Version=v4.0,Profile=Profile4', but 
the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author.
Run Code Online (Sandbox Code Playgroud)

检查包看起来似乎是针对portable-sl4 + wp71 + windows8,但是当我创建一个针对这些框架的vinalla项目时,我无法让它工作(profile4在上面列出,但我尝试了几个不同的看到什么坚持).我刚刚在工作室更新了nuget.从包管理器控制台运行'nuget'会将nuget版本显示为2.1.31022.9038.

如果我浏览到包中的protobuf-net.dll(在lib\_便携式-sl4 + wp71 + windows8下),它将允许我引用它,一切都很好.

我可以手动添加它,但我错过了一些明显的东西.

任何帮助赞赏.

protobuf-net nuget portable-class-library

5
推荐指数
1
解决办法
1230
查看次数

protobuf-net,版本控制和代理类型的最佳实践

我正在尝试使用protobuf-net(Marc Gravell的实现)来确定如何解决这个用例.

  • 我们有A类,它被认为是版本1
  • A类的实例已序列化为磁盘
  • 我们现在有了B类,它被认为是A类的第2版(A类有很多错误,我们必须为下一个版本创建B类).A类仍然存在于代码中,但仅用于传统目的.
  • 我想将版本:1数据(存储到磁盘)反序列化为B类实例,并使用逻辑例程将数据从先前的A类实例转换为B类的新实例.
  • B类实例将在操作期间序列化为磁盘.
  • 应用程序应该期望反序列化A类和B类的实例.

数据契约代理的概念和DataContractSerializer浮现在脑海中.目标是将版本:1数据转换为新的B类结构.

一个例子:

[DataContract]
public class A {

     public A(){}

     [DataMember]
     public bool IsActive {get;set;]

     [DataMember]
     public int VersionNumber {
          get { return 1; }
          set { }
     }

     [DataMember]
     public int TimeInSeconds {get;set;}

     [DataMember]
     public string Name {get;set;}

     [DataMember]
     public CustomObject CustomObj {get;set;} //Also a DataContract

     [DataMember]
     public List<ComplexThing> ComplexThings {get;set;} //Also a DataContract
     ...
}

[DataContract]
public class B {

     public B(A a) {
          this.Enabled = a.IsActive; //Property now has a …
Run Code Online (Sandbox Code Playgroud)

c# versioning protobuf-net

5
推荐指数
1
解决办法
2644
查看次数

ProtoBuf在反序列化期间破坏了字节数组(添加了额外的0)

我正在使用ProtoBuf.NET来序列化/反序列化某些类.我发现在反序列化时,我得到一个损坏的字节[](额外的0).在您提出之前,是的,我需要ProtoBuf API 的*WithLengthPrefix()版本,因为ProtoBuf部分位于自定义流的开头:)

无论如何,我明白了

Original object is (JSON depiction):
{"ByteArray":"M+B6q+PXNuF8P5hl","ByteArray2":"DmErxVQ2y87IypSRcfxcWA==","K":2,"V
":1.0}

Protobuf: Raw Hex (42 bytes):
29-2A-20-0A-0C-33-E0-7A-AB-E3-D7-36-E1-7C-3F-98-65-12-10-0E-61-2B-C5-54-36-CB-CE
-C8-CA-94-91-71-FC-5C-58-08-02-15-00-00-80-3F

Regenerated object is (JSON depiction):
{"ByteArray":"AAAAAAAAAAAAAAAAM+B6q+PXNuF8P5hl","ByteArray2":"DmErxVQ2y87IypSRcf
xcWA==","K":2,"V":1.0}
Run Code Online (Sandbox Code Playgroud)

额外AAA*AByteArray成员基本上都是十六进制为0x00的用base64.

应用程序逻辑类似于

static void Main(string[] args)
{
    var parent = new Parent();
    parent.Init();

    Console.WriteLine("\nOriginal object is (JSON depiction):");
    Console.WriteLine(JsonConvert.SerializeObject(parent));

    using (var ms = new MemoryStream())
    {
        Serializer.SerializeWithLengthPrefix(ms, parent, PrefixStyle.Base128);
        byte[] bytes2 = ms.ToArray();
        var hex2 = BitConverter.ToString(bytes2);
        Console.WriteLine("\nProtobuf: Hex ({0} bytes):\n{1}", bytes2.Length, hex2);

        ms.Seek(0, SeekOrigin.Begin);
        var backFirst = Serializer.DeserializeWithLengthPrefix<Parent>(ms,PrefixStyle.Base128); …
Run Code Online (Sandbox Code Playgroud)

c# protocol-buffers protobuf-net

5
推荐指数
1
解决办法
401
查看次数