首页 > 解决方案 > (de) 使用 System.Text.Json 序列化流

问题描述

我正在尝试使用System.Text.Json 的 JsonSerializer将对象序列化为 MemoryStream 。我无法在文档中找到它的实现/方法。有人可以分享使用 System.Text.Json 进行序列化和反序列化的示例实现吗?

标签: asp.net.netjson-deserializationjsonserializersystem.text.json

解决方案


目前还不清楚问题是什么,或者缺少哪些文档和示例,因为其中包含多个部分docs.microsoft.com以及数百篇博客文章和文章。在文档中JSON 序列化和反序列化是一个很好的起点,How to serialize and deserialize (marshal and unmarshal) JSON in .NET包括Serialize to UTF8部分。

无论如何,MemoryStream只是数组上的 Stream 包装器,因此序列化到 a 与直接序列化到数组相同。这可以通过JsonSerializer.SerializeToUtf8Bytes来完成:byte[]MemoryStreambyte[]

byte[] jsonUtf8Bytes =JsonSerializer.SerializeToUtf8Bytes(weatherForecast);

最后,在 .NET 中,任何需要序列化的东西都通过 Reader 和 Writer 对象工作,例如 TextReader、StreamReader、TextReader 和 -Writers。在 JSON.NET 的情况下,这是通过Utf8JsonWriter对象完成的。JsonSerializer.Serialize具有写入 a 的重载Utf8JsonWriter

using var stream=File.OpenWrite(somePath);
using var writer=new Utf8JsonWriter(stream);
JsonSerializer.Serialize(writer,myObject);

不过,这是缓慢的使用方式System.Text.Json。使用缓冲区意味着分配它们并清理它们,这是昂贵的,尤其是在 Web 应用程序中。出于这个原因,ASP.NET Core 使用IO 管道而不是流来接收和发送数据到套接字,使用从缓冲池中租用的可重用缓冲区并在 ASP.NET Core 管道中的每个步骤中传递。传递byte[]缓冲区会复制它们的内容,因此 .NET Core 引入了Span<>andMemory<>类型,它们表示现有(可能是池化的)缓冲区的视图。这样,ASP.NET Core 传递缓冲区的那些“视图”,而不是缓冲区本身。

System.Text.Json构建为使用管道和可重用内存而不是流,允许 ASP.NET Core 在高流量网站中使用最少的内存和尽可能少的分配。ASP.NET Core 使用Utf8JsonWriter(IBufferWriter)构造函数通过PipeWriter写入输出管道。

我们可以使用相同的重载通过ArrayBufferWriter写入可重用缓冲区。这相当于使用MemoryStream BUT输出可以通过 a 访问,ReadOnlySpan<byte>因此Memory<byte>不必复制它:

using var buffer=new ArrayBufferWriter<byte>(65536);
using var writer=new Utf8JsonWriter(buffer);
JsonSerializer.Serialize(writer,myObject);

ReadOnlySpan<byte> data=buffer.WrittenSpan;

推荐阅读