使用protobuf-net将压缩字节反序列化为Stream成员

时间:2016-06-17 21:10:44

标签: c# .net memory protocol-buffers protobuf-net

有没有办法将bytes字段反序列化为Stream成员,而没有protobuf-net预先分配新的(可能很大的)byte []?

我正在寻找类似的东西:

[ProtoContract]
public class Message
{
    [ProtoMember(1)]
    Stream Payload { get; set; }
}

流可以由预先分配的缓冲池支持,例如Microsoft.IO.RecyclableMemoryStream。即使在下降到ProtoReader进行反序列化之后,我看到的只是AppendBytes,它总是分配一个字段长度的缓冲区。一个人必须进一步下降到DirectReadBytes,这只能直接在消息流上运行 - 我想避免这种情况。

作为背景,我使用protobuf-net对线路上的消息进行序列化/反序列化。这是一个用于在客户端之间传递消息的中间层组件,因此消息实际上是封闭二进制有效负载的包络:

message Envelope {
  required string messageId = 1;
  map<string, string> headers = 2;
  bytes payload = 3;
}

payload的大小限制为~2 MB,但大到足以让字节[]落在LOH中。

使用Protobuf-net: Serializing a 3rd party class with a Stream data member中的代理不起作用,因为它只包含相同的单片阵列。

Memory usage serializing chunked byte arrays with Protobuf-net中提到了一种应该有效的技术,将bytes更改为repeated bytes并依赖发件人来限制每个块。这个解决方案可能已经足够好了,它可以防止LOH分配,但它不会允许缓冲池。

1 个答案:

答案 0 :(得分:1)

这里的问题是关于payload字段。不,目前还没有一种机制可以解决这个问题,但肯定可以对选项进行调查。可能是我们可以对序列化上下文执行类似ArraySegment<byte> AllocateBuffer(int size)回调的操作,调用者可以使用它来控制分配(关于这一点的好处是protobuf-net实际上不能用于{ {1}},所以这将是一个纯粹的增量更改,不会影响任何现有的工作代码;如果没有提供回调,我们可能只是像现在一样分配一个平缓冲区)。我愿意接受其他建议,但现在:不 - 它将在内部分配ArraySegment<byte>