我试图将非常大的对象直接序列化到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();
}
}
谢谢。
与其冲洗写入器,我建议您完全关闭。这样,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
将已经关闭,但没关系-数据仍将在那里。