【问题标题】:How to writte protobuf serialized content directly to SharpZipLib stream如何将 protobuf 序列化内容直接写入 SharpZipLib 流
【发布时间】:2013-10-25 13:16:17
【问题描述】:

是否可以将 protobuf 序列化内容直接写入 SharpZipLib 流?当我尝试这样做时,看起来提供的流没有填充来自 protobuf 的数据。稍后我需要从提供的 Zip 流中取回反序列化的实体。 我的代码如下所示:

private byte[] ZipContent(T2 content)
    {
        const short COMPRESSION_LEVEL = 4; // 0-9
        const string ENTRY_NAME = "DefaultEntryName";


        byte[] result = null;

        if (content == null)
            return result;

        IStreamSerializerProto<T2> serializer = this.GetSerializer(content.GetType());
        using (MemoryStream outputStream = new MemoryStream())
        {
            using (ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream))
            {
                zipOutputStream.SetLevel(COMPRESSION_LEVEL);
                ZipEntry entry = new ZipEntry(ENTRY_NAME);
                entry.DateTime = DateTime.Now;
                zipOutputStream.PutNextEntry(entry);

                serializer.Serialize(zipOutputStream, content);
            }

            result = outputStream.ToArray();
        }

        return result;
    }

private class ProtobufStreamSerializer<T3> : IStreamSerializerProto<T3>
        {
            public ProtobufStreamSerializer()
            {
                ProtoBuf.Serializer.PrepareSerializer<T3>();
            }

    public void Serialize(Stream outputStream, T3 content)
    {
        Serializer.Serialize(outputStream, content);
    }

            public T3 Deserialize(Stream inputStream)
            {
                T3 deserializedObj;
                using (inputStream)
                {
                    deserializedObj = ProtoBuf.Serializer.Deserialize<T3>(inputStream);
                }
                return deserializedObj;
            }
        }

我正在尝试序列化的类的示例:

[Serializable]
    [ProtoContract]
    public class Model
    {
        [XmlElement("ModelCode")]
        [ProtoMember(1)]
        public int ModelCode { get; set; }

                ...

    }

【问题讨论】:

  • 你要序列化的数据是什么?即content 是什么?类型的定义是什么(理想情况下,我可以看到属性),与实例关联的值是什么?
  • 您的编辑仍然不足以让我认为 0 字节是意外的。如果Model都是默认值,写起来没什么意思,完全可以写成0字节。您是否有一个完整的示例来显示我们可能合理预期会占用空间的实际数据
  • 请注意,二进制数据的压缩并非“轻而易举”;它通常可以使输出更大。建议谨慎。

标签: c# protobuf-net sharpziplib


【解决方案1】:

这就是问题所在,我相信(在问题的原始代码中):

public void Serialize(Stream outputStream, T3 content)
{
    using (var stream = new MemoryStream())
    {
        Serializer.Serialize(stream, content);
    }
}

您完全忽略了outputStream,而是将数据仅写入新的MemoryStream,然后将其忽略。

我怀疑你只是想要:

public void Serialize(Stream outputStream, T3 content)
{
    Serializer.Serialize(outputStream, content);
}

我还建议从您的 Deserialize 方法中删除 using 语句:我希望 调用者 在完成输入流后负责处理输入流.您的方法可以简化为:

public T3 Deserialize(Stream inputStream)
{
    return ProtoBuf.Serializer.Deserialize<T3>(inputStream);
}

【讨论】:

  • 是的,你是对的,但在执行该行和 atfer 之前,流具有相同的长度,所以看起来什么也没发生。
  • @Vytas999 好吧,content 中有什么内容? 0 字节是 protobuf 消息的完全有效长度...如果没有什么有趣的东西可写
  • 有一个类包含很多属性值。我编辑了这个问题,详细说明了它的外观。
  • @Vytas999:更改了问题后,我的回答现在看起来毫无意义……如果您至少承认问题的更改,那就太好了。看起来应该没问题 - 如果您序列化为 MemoryStream 而不是 ZipOutputStream,那么会发生什么?您是否可能需要使用ZipOutputStream 明确关闭每个条目?
  • @Vytas999:您根本不需要更改参数类型。如果这真的有所作为,我会感到非常惊讶。也许您在第一次更改后没有正确干净的构建?
【解决方案2】:

代码(Jon 指出的编辑)看起来不错。它在这里工作:

static void Main()
{
    var obj = new Bar{ X = 123, Y = "abc" };
    var wrapper = new Foo<Bar>();
    var blob = wrapper.ZipContent(obj);
    var clone = wrapper.UnzipContent(blob);
}

Bar 在哪里:

[ProtoContract]
class Bar
{
    [ProtoMember(1)]
    public int X { get; set; }
    [ProtoMember(2)]
    public string Y { get; set; }
}

Foo&lt;T&gt; 是你的班级(我不知道名字),我在其中添加了:

public T2 UnzipContent(byte[] data)
{
    using(var ms = new MemoryStream(data))
    using(var zip = new ZipInputStream(ms))
    {
        var entry = zip.GetNextEntry();
        var serializer = this.GetSerializer(typeof(T2));
        return serializer.Deserialize(zip);
    }
}

另外,请注意压缩是双刃剑。在我上面给出的示例中,底层大小(即,如果我们只是写入 MemoryStream)是 7 个字节。 ZipInputStream 将这 7 个字节“压缩”到 179 个字节。压缩在较大的对象上效果最好,通常是在有大量文本内容时。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-03
    • 2015-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-21
    • 1970-01-01
    相关资源
    最近更新 更多