JsonSerializer无法写入GZipStream

本文关键字:GZipStream JsonSerializer | 更新日期: 2023-09-27 18:15:33

我试图将非常大的对象直接序列化到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();
    }
}

谢谢。

JsonSerializer无法写入GZipStream

与其冲洗写入器,我建议您完全关闭。这样,GZipStream就知道没有更多的数据要写,可以添加任何适当的校验和或任何它需要做的事情。

您可以显式地调用Close,或者将其放在using语句的结束部分之间:

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将已经关闭,但没关系-数据仍将在那里。