JsonSerializer无法写入GZipStream

4
我正在尝试将非常大的对象直接序列化到zip流中。我通过在中间步骤将其序列化到文件流中,重新加载它,然后压缩它来实现此目标。
我还尝试直接压缩到内存流中,并且它也可以工作。但当我使用GZipStream时,总是留下一个“未完成”的对象,数据存在并且格式正确,只是在意料之外地结束了。
这不是因为缓冲区刷新不足,因为我已经尝试过刷新一切。
简化的示例代码:
internal static byte[] SerializeAndCompress(object objectToSerialize)
{
    using(var memStream = new MemoryStream())
    using (var zipStream = new GZipStream(memStream, CompressionMode.Compress, true))
    using (var streamWriter = new StreamWriter(zipStream))
    using (var jsonWriter = new JsonTextWriter(streamWriter))
    {
        var jsonSerializer = new JsonSerializer { ContractResolver = new CamelCasePropertyNamesContractResolver(), Formatting = Newtonsoft.Json.Formatting.None };

        jsonSerializer.Serialize(jsonWriter, objectToSerialize);
        jsonWriter.Flush();

        return memStream.ToArray();
    }
}

谢谢。
1个回答

13

我建议您完全关闭写入器(writer)而不是清空它。这样,GZipStream就知道没有更多的数据要写入,并可以添加任何适当的校验和或其他需要完成的操作。

您可以显式调用Close,也可以将其放置在使用语句的关闭部分之间:

using(var memStream = new MemoryStream())
{
    using (var zipStream = new GZipStream(memStream, CompressionMode.Compress, true))
    using (var streamWriter = new StreamWriter(zipStream))
    using (var jsonWriter = new JsonTextWriter(streamWriter))
    {
        var jsonSerializer = new JsonSerializer { ContractResolver = new CamelCasePropertyNamesContractResolver(), Formatting = Newtonsoft.Json.Formatting.None };

        jsonSerializer.Serialize(jsonWriter, objectToSerialize);
    }
    return memStream.ToArray();
}
请注意,在调用 ToArray 时,MemoryStream 已经关闭,但没关系——数据仍然存在。

谢谢,这似乎解决了问题。我需要进行更多的测试以确保。它适用于大对象,但由于某种原因,对于较小对象的测试代码却不起作用。 - pnsm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接