使用 protobuf-net 将打包字节反序列化为 Stream 成员
Deserializing packed bytes to a Stream member with 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 来 serialize/deserialize 通过网络传输消息。这是一个用于在客户端之间传递消息的中间层组件,因此消息实际上是一个包含二进制负载的信封:
message Envelope {
required string messageId = 1;
map<string, string> headers = 2;
bytes payload = 3;
}
payload
的大小限制为 ~2 MB,但足以让 byte[] 落入 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 分配,但它不允许缓冲池。
这里的问题是关于 payload
字段的。不,目前没有一种机制来处理这个问题,但肯定是可以研究选择的东西。可能是我们可以在序列化上下文上执行类似 ArraySegment<byte> AllocateBuffer(int size)
回调的操作,调用者可以使用它来控制分配(这样做的好处是 protobuf-net 实际上不适用于 ArraySegment<byte>
,所以这将是一个纯粹的增量更改,不会影响任何现有的工作代码;如果没有提供回调,我们大概会像现在一样分配一个平面缓冲区)。我对其他建议持开放态度,但现在:不 - 它会在内部分配一个 byte[]
。
有没有一种方法可以将 bytes
字段反序列化为 Stream 成员,而无需 protobuf-net 预先分配一个新的(可能是大的)byte[]?
我正在寻找这样的东西:
[ProtoContract]
public class Message
{
[ProtoMember(1)]
Stream Payload { get; set; }
}
流可以由预分配的缓冲池支持,例如Microsoft.IO.RecyclableMemoryStream
。即使在下降到 ProtoReader
进行反序列化之后,我所看到的只是 AppendBytes
,它总是分配一个字段长度的缓冲区。必须进一步下降到 DirectReadBytes
,它只直接在消息流上运行——我想避免这种情况。
作为背景,我正在使用 protobuf-net 来 serialize/deserialize 通过网络传输消息。这是一个用于在客户端之间传递消息的中间层组件,因此消息实际上是一个包含二进制负载的信封:
message Envelope {
required string messageId = 1;
map<string, string> headers = 2;
bytes payload = 3;
}
payload
的大小限制为 ~2 MB,但足以让 byte[] 落入 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 分配,但它不允许缓冲池。
这里的问题是关于 payload
字段的。不,目前没有一种机制来处理这个问题,但肯定是可以研究选择的东西。可能是我们可以在序列化上下文上执行类似 ArraySegment<byte> AllocateBuffer(int size)
回调的操作,调用者可以使用它来控制分配(这样做的好处是 protobuf-net 实际上不适用于 ArraySegment<byte>
,所以这将是一个纯粹的增量更改,不会影响任何现有的工作代码;如果没有提供回调,我们大概会像现在一样分配一个平面缓冲区)。我对其他建议持开放态度,但现在:不 - 它会在内部分配一个 byte[]
。